前端
一点也不简单

React的基础知识

React的起源和发展

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

React与传统MVC的关系

轻量级的视图层A JavaScript library for building user interfaces

React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;React 构建页面 UI 的库。可以简单地理解为,React 将将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。

React高性能的体现:虚拟DOM

React高性能的原理:

原因:

web开发中需要将变化的数据实时反应到UI(视图)上 ,需要DOM操作,然而频繁的DOM操作会导致严重的性能问题, 因此React为此引入了虚拟DOM(Virtual DOM)的机制

什么是 虚拟DOM(Virtual DOM)机制

待补充~~

React的虚拟DOM算法

react 16以前:和vue一样采用diff算法

react 16以后:采用 React Fiber

React Fible的原理

React Fiber的方法其实很简单——分片。把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,虽然总时间依然很长,但是在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。

React的特点和优势

虚拟DOM

组件系统

单项数据流

JSX语法

React起步

组件:

  • 函数式组件:
function App() {
  return (
    <div className="App">
      <p>我是函数式组件</p>
    </div>
  );
}
  • class组件:
import React,{ Component } from 'react'
class Home extends React.Component{
    render () {
        return (
           <div className="App">
      <p>我是函数式组件</p>
    </div>
        )
    }
}
  • 组件的组合和嵌套
import React from 'react'
import {Fragment} from 'react'
class A extends React.Component{
    render () {
        return (
            <div>A</div>
        )
    }
}
class B extends React.Component{
    render () {
        return (
            <div>B</div>
        )                      
    }
}
class Detail extends React.Component{
    render () {
        return (
            <Fragment>
                <A></A>
                <B></B>
            </Fragment>
        )
    }
}
export default Detail

Detail组件里嵌套了A组件和B组件

Fragment的作用

  1. 代替唯一根元素,并且不会被渲染
  2. 不会生成外层的元素

JSX原理

要明白JSX的原理,需要先明白如何用 JavaScript 对象来表现一个 DOM 元素的结构?

看下面的DOM结构

<div class='app' id='appRoot'>
  <h1 class='title'>欢迎进入React的世界</h1>
  <p>
    React.js 是一个帮助你构建页面 UI 的库
  </p>
</div>

上面这个 HTML 所有的信息我们都可以用 JavaScript 对象来表示:

{
  tag: 'div',
  attrs: { className: 'app', id: 'appRoot'},
  children: [
    {
      tag: 'h1',
      attrs: { className: 'title' },
      children: ['欢迎进入React的世界']
    },
    {
      tag: 'p',
      attrs: null,
      children: ['React.js 是一个构建页面 UI 的库']
    }
  ]
}

但是用 JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。

下面代码:

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  render () {
    return (
      <div className='app' id='appRoot'>
        <h1 className='title'>欢迎进入React的世界</h1>
        <p>
          React.js 是一个构建页面 UI 的库
        </p>
      </div>
    )
  }
}

ReactDOM.render(
	<App />,
  document.getElementById('root')
)

编译之后将得到这样的代码:

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  render () {
    return (
      React.createElement(
        "div",
        {
          className: 'app',
          id: 'appRoot'
        },
        React.createElement(
          "h1",
          { className: 'title' },
          "欢迎进入React的世界"
        ),
        React.createElement(
          "p",
          null,
          "React.js 是一个构建页面 UI 的库"
        )
      )
    )
  }
}

ReactDOM.render(
	React.createElement(App),
  document.getElementById('root')
)

React.createElement` 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等, 语法为

React.createElement(
  type,
  [props],
  [...children]
)

所谓的 JSX 其实就是 JavaScript 对象,所以使用 React 和 JSX 的时候一定要经过编译的过程:

JSX —使用react构造组件,bable进行编译—> JavaScript对象 — ReactDOM.render()—>DOM元素 —>插入页面

组件内的DOM样式

  • 行内样式

想给虚拟dom添加行内样式,需要使用表达式传入样式对象的方式来实现:

// 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
 <p style={{color:'red', fontSize:'14px'}}>Hello world</p>

行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方,例如render函数里、组件原型上、外链js文件中

  • class样式

平常我们用的是class但在react里class应该写为className

<p className="hello" style = {this.style}>Hello world</p>
  • 不同的条件添加不同的样式

有时候需要根据不同的条件添加不同的样式,比如:完成状态,完成是绿色,未完成是红色。那么这种情况下,我们推荐使用classnames这个包:

  • css-in-js

styled-components是针对React写的一套css-in-js框架,简单来讲就是在js中写css。npm链接

组件的数据挂载方式

属性(props)

props正常是外部传入的,

组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更改,但是你可以通过父组件主动重新渲染的方式来传入新的 props

属性是描述性质、特点的,组件自己不能随意更改。

class Title extends Component {
  render () {
    return (
  	    <h1>欢迎进入{this.props.name}的世界</h1>
  	)
    }
}
class App extends Component {
  name="React"
  render () {
    return (
  	<Fragment>
      	    <Title name="React" />
        </Fragment>
  	)
  }
}

props.children

我们知道使用组件的时候,可以嵌套。要在自定义组件的使用嵌套结构,就需要使用 props.children 。在实际的工作当中,我们几乎每天都需要用这种方式来编写组件。

然而,当父组件这样使用子组件时:(使用子组件时在子组件双标签里写了东西)

class App extends Component {
  render () {
    return (
  		<Fragment>
      	<Title>React</Title>
        <Content><i>React.js</i>是一个构建UI的库</Content>
      </Fragment>
  	)
  }
}

这种情况页面中不会显示子组件的内容,会被React.js是一个构建UI的库替换掉,name我们如何解决呢???

答案:子组件中使用props.children

class Title extends Component {
  render () {
    return (
  		<h1>欢迎进入{this.props.children}的世界</h1>
  	)
  }
}

const Content = (props) => {
  return (
    <p>{props.children}</p>
  )
}

使用prop-types验证props

生产环境使用

npm i prop-types -S

引入

import PropTypes from 'prop-types'

组件Child里使用

Child.propTypes={//属性验证
    name: PropTypes.number
}
赞(1) 打赏
未经允许不得转载:专注前端开发和vps技术交流的博客-纸飞机 » React的基础知识

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

微信扫一扫打赏