react官方文档总结(基础篇)

415 阅读8分钟

前言:阅读官方文档,可以跟着作者的思路,去了解框架的整体结构和基础知识。不经间透露出的设计思想和作者对知识点的深入浅出的描述,都会让人受益匪浅。本文是对官方文档的总结、归纳,方便后续的查阅复习,也有本人主观的一些理解。

一、核心概念

JSX语法:

JSX语法诞生的原因:

  • react是一个JS库,更方便操作JS对象
  • DOM的频繁操作会增大浏览器的性能开销
  • 如何能即写HTML标签,又可以把它当成JS对象去操作

JSX语法的本质:

  • JSX其实是react.createElement(componentName, props, ...children)的语法糖,映射为虚拟DOM

下面官网3张图,生动表现了,JSX的解析过程(JSX映射为虚拟DOM对象)

1.png 2.png 3.png

JSX的安全性:

  • 渲染输入的内容时,会转换为字符串,可以防止XSS攻击(cross-site-scripting跨站脚本)

关于Props和State数据的生动解释:

  • React中的Props数据就像瀑布中的水流,自上而下,而State可以在任意一点上给瀑布增加额外的水源

4.jpg

props数据:

  • 外部传入组件的,只读数据

state数据:

  • 组件作用域的数据

  • setState()方法的细节:

      1. React会把多个setState()合并成一个,用以提升性能。
      2. Reactthis.propsthis.state可能会异步更新
      3. 保证拿到前一刻的state和props的方式:
          this.setState((state,props) => { counter: state.counter + props.increment })
      注意:
          setState()当前是同步方法,
          因为React的实现机制导致了异步的错觉,
          放入setTimeout中超脱React执行流时,可以看到时同步执行的 
          
    

关于事件处理:

  • 推荐用法:onClick={this.arrowFunc(this, id)}(arrowFunc是箭头函数的引用,这样每次不会每次render()时,生成新的函数,同时this也默认绑定到了组件上)
  • 兼容问题:使用SyntheticEvent包装器,即浏览器的原生事件的包装器(拥有浏览器所有原生事件的接口,兼容所有浏览器)

react的slot实现:

  • 默认slot:return (<div>{props.children}</div>)

      使用:组件标签内的 所有内容 替换 {props.children}
    
  • 具名slot:return (<div><div>{props.left}</div><div>{props.right}</div></div>)

      使用:组件标签中的 left对象 替换 {props.left} / right对象 替换 {props.right}
    

key属性的作用:

  • 标识DOM的唯一性(带来的好处):

      1. 便于diffing算法找出最小的更新,减少开销
      2. 也可以修改key,强制更新
    

.

二、高级指引

无障碍:

  • 示例:Accessibility => a11y (例如 HTML 属性 aria-* 屏幕阅读器使用 )

代码分割:

  • 概念:将代码分包,只有使用到这个代码包才去加载

  • 优点:减少不必要代码的加载,提升响应速度

  • 实践:

      1. 微信小程序的分包配置
      2. vue react 前端框架支持的路由动态加载
    

context:

  • 概念:父组件的数据,提供给所有子组件使用,所有子组件都能访问到这些数据

  • 用法:

    创建context:ThemeContext = React.createContext('light');

    父组件中提供context:<ThemeContext.Provider value="dark">父组件</ThemeContext.Provider>

    子组件中获取context:

    1. class组件:

      组件内 static contextType = ThemeContext;

      组件外 MyClass.contextType = ThemeContext;

    2. 函数组件:

      <ThemeContext.Consumer>函数组件(context)</ThemeContext.Consumer>

  • 优点:减少props的层层传递

  • 缺陷:增加了父子组件的耦合,不便于子组件的复用

错误边界:

  • 使用 static getDerivedStateFromError() 渲染备用 UI
  • 使用 componentDidCatch() 打印错误信息

Refs:

  • 推荐用法:

    class组件内:React.createRef()

    函数组件内:useRef(initialValue)

  • 过时用法:

    this.refs.textInput

  • refs使用的地方:

    HTML元素:current上挂载DOM对象

    class组件:current上挂载class组件的实例对象

    函数组件:配合forwardRef、useImperativeHandle,current上可以挂载函数组件的属方

  • Refs转发:

    class组件:直接做为属性,穿透class,给到子组件

    函数组件:配合forwardRef,在内部获取到,给到子组件

  • Refs回调用法(class组件和函数组件都适用):

    原理:使用函数,去获取组件/DOM的引用

    示例:ref={el => this.inputElement = el}

Fragments:

  • 一个包裹性的占位标签,原生写法React.Fragment(可以支持key属性),简写<></>

高阶组件:

  • 它应该是一个纯函数组件,接受一个组件参数,返回一个新的组件

深入JSX:

  • 本质:JSX其实是react.createElement(componentName, props, ...children)的语法糖,其实本质本质就是虚拟DOM

  • 语法:

    组件名:

    1. 必须是大写字母开头
    2. 不能使用通用表达式(通用表达式即:对象[变量名])

    属性值:默认值是true

    子元素:可以将任何东西作为子元素传递给自定义组件

  • 不会渲染的值:true,false, undefined, null 是合法的子元素。但它们并不会被渲染

性能优化:

  • DOM更新提速的方式:

    1. 使用shouldComponentUpdate(nextProps, nextState)生命周期函数(默认返回ture)

      原理:通过返回是true/false,控制DOM是否更新(但影响不到它的子组件)

    2. 继承React.PureComponent,使用浅比较,控制DOM更新

      原理:浅比较props和state,是否变化来控制DOM更新(更深层的引用,察觉不到)

createPortal:

  • 作用:给任意DOM节点,添加子节点(ReactDOM.createPortal(child, container))
  • 副作用:createPortal方法添加的子节点,结构上属于被添加到的父节点上,事件上又属于它之前的位置

Profiler组件:

  • 作用:测量该组件内的DOM渲染花销

  • 用法:<Profiler id="Navigation" onRender={callback}>被测量的DOM</Profiler>

    onRender函数的作用:获取渲染花销的具体数据

Render Props:

  • 本质:函数作为属性传递进父组件,该函数返回使用父组件数据的子组件
  • 作用:实现了类似高阶组件的功能,父组件可以接受不同的子组件,并返回新组件

严格模式:

  • 作用:突显应用程序中潜在问题的工具

  • 潜在问题的类型:

    1. 不安全的生命周期(比如componentWillMount())
    2. 使用过时字符串 ref API 的警告
    3. 过时的 context API
    4. 使用废弃的 findDOMNode 方法的警告
    5. 意外的副作用
  • 示例:<React.StrictMode>被严格模式检查的内容</React.StrictMode>

使用 PropTypes 类型检查:

  • 用法:

    import PropTypes from 'prop-types

    class组件名/函数组件名.propTypes = { name: PropTypes.string }

输入组件的类型:

  • 非受控组件:

    本质:数据通过ref,交给DOM节点管理(获取方式this.inputRef.current.value)

  • 受控组件:

    本质:传统用法,数据通过表单事件,交给state管理 .

三、React class 组件的API

生命周期中的API调用顺序:

  • 挂载时:

    constructor()

    1. 作用:

      初始化this.state

      为函数绑定thisthis.handleClick = this.handleClick.bind(this);

    static getDerivedStateFromProps()(不常用)

    1. 作用:

      在render()前调用,返回一个对象来更新state,返回null则不更新

    render()

    1. 作用:

      通常是返回react元素(组件、jsx)

    2. 特点:

      class组件中唯一必须实现的方法

      它是纯函数,输出结果只受state/props的影响

    componentDidMount()

    1. 作用:

      在组件挂载后,浏览器更新屏幕前,去执行额外的数据请求、DOM操作

  • 更新时:

    static getDerivedStateFromProps()(上面已解释)

    shouldComponentUpdate()(不建议用)

    1. 作用:

      根据 props 或 state 的变化,判断是否更新当前组件,但对子组件的更新无影响(不建议用的原因)

    2. 特点:

      当 props 或 state 发生变化时,会在render()之前被调用。返回值默认为 true。

      返回false时,后续的 render() 和 componentDidUpdate() 不会调用

    render()(上面已解释)

    getSnapshotBeforeUpdate()(不常用)

    1. 作用:

      在最近一次渲染前调用,可以获取更新前的DOM信息

    2. 特点:

      返回的值会给到componentDidUpdate()

    componentDidUpdate()

    1. 作用:

      更新后会被立即调用,可以在条件语句里执行一些 数据请求、DOM操作

  • 卸载时:

    componentWillUnmount()

    1. 作用:

      组件卸载时,做一些清除副作用的操作

  • 生命周期中出错时:

    getDerivedStateFromError()(未来版本,可能会使用)

    1. 作用:

      捕获渲染阶段错误,可用来渲染备用UI

    componentDidCatch()(当前版本,建议使用)

    1. 作用:

      捕获提交阶段错误,可用来打印错误信息

其他API:

setState()

  1. 作用:

    给组件内作用域的state,设置值

  2. 特点:

    当前是同步方法,容易被react的执行机制误导为异步方法

forceUpdate()(不建议使用,尽量用state、props的变化驱动组件渲染)

  1. 作用:

    使组件调用render(),强制组件重新渲染

Class 属性:

defaultProps:

  1. 作用:

    给class组件,添加默认的props

displayName

  1. 作用:

    调试消息时,高阶组件中区分子组件的名称

.

四、ReactDOM的API

render()

  1. 作用:

    浏览器端渲染组件

hydrate()

  1. 作用:

    貌似是服务端渲染, 它用于在 ReactDOMServer 渲染的容器中对 HTML 的内容进行 hydrate 操作(后续加强了解)

unmountComponentAtNode()

  1. 作用:

    从 DOM 中卸载组件

findDOMNode()

  1. 作用:

    访问底层 DOM 节点的应急方案,不推荐使用的API

createPortal()

  1. 作用:

    将子节点渲染到 DOM 节点中的方式(产生的副作用已在上面说明)

.

五、ReactDOMServer

  • 原理:

    在Node服务端,将react组件,渲染成静态标记

  • 作用:

    服务端渲染,提升首屏加载速度,和seo优化

  • 常用API:

    renderToString()

    1. 作用:

      将react组件,渲染成HTML字符串

    enderToStaticMarkup()

    1. 作用:

      将react组件,渲染成HTML字符串,会去除额外的属性

    renderToNodeStream()

    1. 作用:

      将react组件,渲染成HTML字符串的可读流

    renderToStaticNodeStream()

    1. 作用:

      将react组件,渲染成HTML字符串的可读流,会去除额外的属性

.

六、React的DOM系统

  • 兼容:

    兼顾性能的同时,兼容所有浏览器

  • 属性:

    属性名称,小驼峰的方式

    在HTML属性的基础上,也有一套自己的定义的属性 .

七、其它

  • mixins被抛弃的原因:

      1.mixins中的隐式依赖
      2.mixins之间的依赖关系混乱
      3.mixins之间的函数命名的冲突
    

.

写在最后:以上就是阅读官方文档后,总结的内容,可以作为复习纲要,更细节深入的内容可以以此进行搜索查阅。