美文网首页
聊一聊,React中一些优化的点

聊一聊,React中一些优化的点

作者: Herrylo | 来源:发表于2019-11-25 23:29 被阅读0次
    images.jpeg

    原文永久链接: https://github.com/AttemptWeb.....

    下面说到的React开发中注意的问题,部分是自己遇到过的点,部分是收集的,也算是React代码优化部分,这次做一个整理,希望可以帮助到你

    避免重复渲染

    当组件的props 或者 state 改变时,可能会出现重复setState的情况,对于重复的操作,我们可以通过下面的方法来避免重复渲染:

    shouldComponentUpdate

    shouldComponentUpdate 返回true,确认真实DOM需要改变时,返回true。一般的做法是比较组件的props和state是否真的发生变化,如果发生变化则返回true,否则返回false。

    shouldComponentUpdate(nextProps, nextState) {
        if (this.props.id !== nextProps.id) {
          return true;
        }
        if (this.state.type !== nextState.type) {
          return true;
        }
        return false;
      }
    

    React文档:shouldComponentUpdate()

    React文档:shouldComponentUpdate 的作用

    React.PureComponent

    React.PureComponent,不必写你自己的shouldComponentUpdate,它提供了一个浅比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。在你的 props 和 state 较为简单时,可以使用 React.PureComponent。(补充:当你比较的目标为引用类型数据,浅比较会忽略属性或状态)

    class ChildComponent extends React.PureComponent {
      render() {
        return(
          <>{this.state.type}</>
        )
      }
    }
    

    React文档:React.PureComponent

    不可变Immutable

    不可变Immutable,Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。更多详情:Immutable 详解及 React 中实践

    import { Map, is } from 'immutable';
    
    constructor() {
      this.state = {
        // 创建 不可变Immutable
        data: Map({ times: 0 })
      }
    }
    shouldComponentUpdate(nextProps, nextState) {
      for (const key in nextState) {
        // 通过 is 或者 !== 来比对
        if (this.state[key] !== nextState[key] && !is(this.state[key], nextState[key])) {
          return true;
        }
      }
    }
    handleAdd() {
      // 一个全新的对象
      const newData = this.state.data.update('times', v => v + 1);
      this.setState({ data: newData);
    }
    

    不可变Immutable,目前我还没有在项目中尝试过,内容来源于社区,如果有相关文章,可以推荐给我。

    Immutable 详解及 React 中实践

    组件优化

    React的key标识

    key 帮助React识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。对于列表组件,key 最好是这个元素在列表中拥有的一个独一无二的字符串

    listData.map((item) =>
      <li key={item.id}>
        {item.text}
      </li>
    );
    

    列表组件 Diff比对时,使用元素在数组中的下标作为 key,列表顺序发生修改,就代表原来的React节点组件无法复用,须创建新的React.Element节点,这样diff 会变得慢。

    当基于下标的组件进行重新排序时,组件基于它们的 key 来决定是否更新以及复用,如果 key 是一个下标,那么修改顺序时会修改当前的 key,导致组件的 state(比如输入框)可能相互篡改导致无法预期的变动。

    React文档:key

    虚拟化长列表

    虚拟列表是常见的‘长列表'和'复杂组件树'优化方式,它优化的本质就是减少渲染的节点。只渲染当前视口可见元素。

    虚拟列表适用场景:无限滚动列表, 表格,下拉列表,大数据量或无限嵌套的树等。

    相关组件方案:

    react-virtualized
    react-window

    React文档:虚拟化长列表

    React.memo

    随着React的版本不断升级,函数式组件功能越来越强大,这也符合它的最初提倡的UI = fn(e)。随着Hooks、memo的支持,函数组件已非常的成熟。

    React.memo为高阶组件,可以使用它替换现有的函数组件。它与 React.PureComponent 非常相似,但它适用于函数组件,但不适用于 class 组件

    function areEqual(prevProps, nextProps) {
      /*
      如果把 nextProps 传入 render 方法的返回结果与
      将 prevProps 传入 render 方法的返回结果一致则返回 true,
      否则返回 false
      */
    }
    function Component(props) {
    
    }
    React.memo(Component, areEqual)
    

    第一个参数是函数组件,第二个参数非必须,主要是props的比较。默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。

    React文档:React.memo

    不滥用props和state

    不论是 props和state 尽量只传需要的数据,避免多余的更新。对于项目的后期维护特别重要。(我已经踩坑了。。。)

    <ListInfoCard data={...state}>
    

    拆分组件

    列表组件、表单组件、商品卡片、icon组件,尽量做到适度的拆分,业务组件和展示组件的分离,易于后期的维护和迭代,同时也可以提升性能。在平时开发中,对于一个单独的页面,数据量不大,直接将业务和展示组件捆绑在一起,在初期,这个是无关痛痒的,如果是一次性开发,问题也不是特别大,但是一旦去要后期的迭代优化,就有问题了。

    从性能角度看react组件拆分的重要性

    结束

    自己遇到开发方面的问题基本就这些了,上面提到的基本都是我遇到过的和研究过的,希望可以帮助到你。这些只是React项目代码层面的东西,如果你需要做一些优化方面的工作,也可以从打包、编译入手。

    相关文章

      网友评论

          本文标题:聊一聊,React中一些优化的点

          本文链接:https://www.haomeiwen.com/subject/vuuswctx.html