iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >React中如何减少props改变
  • 431
分享到

React中如何减少props改变

2024-04-02 19:04:59 431人浏览 泡泡鱼
摘要

这篇文章主要介绍了React中如何减少props改变,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。React性能优化的一个核心点就是减少re

这篇文章主要介绍了React中如何减少props改变,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

React性能优化的一个核心点就是减少render的次数。如果你的组件没有做过特殊的处理(SCU -- shouldComponentUpdate或使用PureComponent),那每次父组件render时,子组件就会跟着一起被重新渲染。通常一个复杂的子组件都会进行一些优化,比如:SCU 使用PureComponent组件。对于SCU基本上进行的也都是浅比较,深比较的代价太高。

对于这些被优化的子组件,我们要减少一些不必要的props改变:比如事件绑定。对于那些依赖于配置项的组件,我们更是减少这些作为props的配置的变化,因为可能一但配置项发生了变化,整个组件都会跟着重新渲染,所以我们要尽可能的减少props的改变

事件绑定

class ClickMe extends React.Component {
  state = {
    value: '3333',
  };

  render() {
    return (
      <Button
        onClick={() => {
          console.log('l am clicked!', this.state.value);
        }}
      >
        click me
      </Button>
    )
  }
}

相信大多数的开发React都会指出这种写法的缺点:每次ClickMe组件渲染的时候onClick属性与上一次的值相比都是一个不同的匿名函数,如果Button是一个复杂的子组件且内部没有经过任何特殊的处理,那就会造成多余的渲染。对于这种情况的做法一般有两种方式:

  1. 在构造函数内绑定 this

  2. 将箭头函数赋予class的属性

class ClickMe extends React.Component {
  state = {
    value: '3333',
  };

  handleClick = () => {
    console.log('l am clicked!', this.state.value);
  };

  render() {
    return (
      <Button
        onClick={this.handleClick}
      >
        click me
      </Button>
    )
  }
}

// 或
class ClickMe extends React.Component {
  constuctor(props) {
    super(props);
    this.state = {
      value: '3333',
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.log('l am clicked!', this.state.value);
  }

  render() {
    return (
      <Button
        onClick={this.handleClick}
      >
        click me
      </Button>
    )
  }
}

批量事件绑定

那在考虑下面这种情况,涉及到子组件的批量绑定时:

class MultiClick extends React.Component {
  dataSource = [
    { key: '1', value: '1' },
    { key: '2', value: '2' },
    { key: '3', value: '3' },
    { key: '4', value: '4' },
  ];

  handleClick = key => {
    console.error('key:', key);
  };

  render() {
    return (
      <div>
        {this.dataSource.map(item => (
          <div
            key={item.key}
            onClick={() => {
              this.handleClick(item.key);
            }}
          >
            {item.value}
          </div>
        ))}
      </div>
    );
  }
}

类似于这种需要传递参数的情况,该如何去优化?

这个就需要我们去做数据的缓存,即回调的缓存,上述例子如下:

cacheMap = {};

genClickHandler = key => {
  if (!this.cacheMap[key]) {
    this.cacheMap[key] = () => {
      console.error('key:', key);
    };
  }
  return this.cacheMap[key];
};

// 绑定
<div key={item.key} onClick={this.genClickHandler(item.key)}>
  {item.value}
</div>;

如果多个基本类型的参数可以,将他们拼接成字符串作为cacheMap的key,简单的引用类型可以使用JSON.stringify,不过原则上作为事件绑定的函数 传递的参数简单为好。

作为配置的props缓存

说到数据的缓存,不管光是事件的回调,还有很多 其他情况。比如表格的 columns需要根据属性变化的这种场景:

class TableDemo extends React.Component {
  getColumns = () => {
    const { name } = this.state;
    return [
      {
        key: '1',
        title: `${name}_1`,
      },
      {
        key: '2',
        title: `${name}_2`,
      },
    ];
  };

  render() {
    const { dataSource } = this.props;
    return <Table dataSource={dataSource} columns={this.getColumns()} />;
  }
}

这种情况每次组件render的时候,getColumns都会被调用一次,而这个函数每次的返回值都是不一样的 ,及时这两次的name值都相等,原因大家可以类比[] !== []这里就不过多叙述了。

有一种做法是,将columns作为一个this.state的一个属性,在初始化和每次 this.state.name改变的时候同步改变this.state.columns的值,但如果有多个 类似于this.state.name的变量控制this.state.columns的值时候,发现每个变量变化的时候都要调用生成columns的方法, 十分的烦琐易造成错误。

使用缓存可以很好的解决这个问题,在参数较为复杂的时候,我们选择只缓存上一次的值。先看代码再说:

首先我们写一个缓存的函数

function cacheFun(cb) {
  let preResult = null
  let preParams = null
  const equalCb = cb || shallowEqual
  return (fun, params) => {
    if (preResult && equalCb(preParams, params)) {
      return preResult
    }
    preResult = fun(params)
    preParams = params
    return preResult
  }
}

这个缓存函数是一个闭包函数,保存了上一次的参数和上一次的结果,主要的实现就是比较两次的参数,相同则返回上一次结果,不同则返回 调用函数的新结果。当然 对于某些特殊的情况只需要根据传入特定的某几个参数做出判断,这种情况你可以传入自定义的比较函数。先看一下上面的实现:

cacheFun函数第一个参数为选填的选项,是你比较两次参数的 方法,如果你不传入则仅进行 浅比较(与 React 的浅比较相似)。

返回函数的第一个参数为你的 生成columns的回调,params 为你需要的 变量,如果你的变量比较多,你可以将他们 作为一个对象传入;那么代码就类似如下:

const params = { name, time, handler };
cacheFun(this.getColumns, params, cb);

在类中的使用为:

class TableDemo extends React.Component {
  getColumns = name => {
    return [
      {
        key: '1',
        title: `${name}_1`,
      },
      {
        key: '2',
        title: `${name}_2`,
      },
    ];
  };

  getColumnsWrapper = () => {
    const { name } = this.state;
    return cacheFun()(this.getColumns, name);
  };

  render() {
    const { dataSource } = this.props;
    return (
      <Table dataSource={dataSource} columns={this.getColumnsWrapper()} />
    );
  }
}

假如你不喜欢对象的传值方式,那你可以 对这个缓存函数进行更改:

function cacheFun(cb) {
  let preResult = null;
  let preParams = null;
  const equalCb = cb || shallowEqual;
  return (fun, ...params) => {
    if (preResult) {
      const isEqual = params.ervey((param, i) => {
        const preParam = preParams && preParams[i];
        return equalCb(param, preParam);
      });
      if (isEqual) {
        return preResult;
      }
    }
    preResult = fun(params);
    preParams = params;
    return preResult;
  };
}

你这可以这样使用:

cacheFun()(this.getColumns, name, key, param1, params2);
// 或者
cacheFun()(this.getColumns, name, key, { param1, params2 });

这样配置也就被缓存优化了,当TableDemo组件因非name属性render时,这时候你的columns还是返回上一次缓存的值,是的Table这个组件减少了一次因columns引用不同产生的render。如果Table的dataSource数据量很大,那这次对应用的优化就很可观了。

数据的缓存

数据的缓存在原生的内部也有使用cacheFun的场景,如对于一个list 根据 searchStr模糊过滤对于的subList

大致代码如下:

class SearchList extends React.Component {
  
  state = {
    list: [
      { value: '1', key: '1' },
      { value: '11', key: '11' },
      { value: '111', key: '111' },
      { value: '2', key: '2' },
      { value: '22', key: '22' },
      { value: '222', key: '222' },
      { value: '2222', key: '2222' },
    ],
    searchStr: '',
  }

  // ...

  render() {
    const { searchStr, list } = this.state
    const dataSource = list.filter(it => it.indexOf(searchStr) > -1)
    return (
      <div>
        <Input onChange={this.handleChange} />
        <List dataSource={dataSource} />
      </div>
    )
  }
}

对于此情景的优化使用cacheFun也可以实现

const dataSource = cacheFun()((plist, pSearchStr) => {
  return plist.filter(it => it.indexOf(pSearchStr) > -1)
}, list, searchStr)

但是有大量的类似于此的衍生值的时候,这样的写法又显得不够。社区上出现了许多框架如配合react-redux使用reselect(当然也可以单独使用,不过配合redux使用简直就是前端数据管理的一大杀手锏),还有mobx的衍生概念等。这些后续会单独介绍,这里就稍微提一下。

感谢你能够认真阅读完这篇文章,希望小编分享的“React中如何减少props改变”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网node.js频道,更多相关知识等着你来学习!

--结束END--

本文标题: React中如何减少props改变

本文链接: https://www.lsjlt.com/news/76222.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React中如何减少props改变
    这篇文章主要介绍了React中如何减少props改变,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。React性能优化的一个核心点就是减少re...
    99+
    2024-04-02
  • vue和react中props变化后如何修改state
    目录vue和react中props变化后修改state改进react改变state必须知道的知识点1.不能直接修改state2.state的更新是异步的3.state的更新是一个合并...
    99+
    2022-11-13
    vue中props react中props props修改state
  • react如何改变title
    这篇“react如何改变title”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“react...
    99+
    2024-04-02
  • react如何改变css样式
    这篇文章主要介绍“react如何改变css样式”,在日常操作中,相信很多人在react如何改变css样式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”react如何改变css样式”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-04
  • React中如何传入组件的props改变时更新组件的几种实现方法
    这篇文章将为大家详细讲解有关React中如何传入组件的props改变时更新组件的几种实现方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。何时使用派生状态咱们先来看一个比...
    99+
    2024-04-02
  • react如何改变组件大小
    这篇文章主要讲解了“react如何改变组件大小”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react如何改变组件大小”吧!react改变组件大小的方法:1、使用“React.cloneEl...
    99+
    2023-07-04
  • react如何改变组件状态
    这篇文章主要介绍“react如何改变组件状态”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“react如何改变组件状态”文章能帮助大家解决问题。在react中,可以利用setState()来修改组件的...
    99+
    2023-07-04
  • react如何改变列表状态
    本篇内容介绍了“react如何改变列表状态”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!react改变列表状态的方法:1、打开相应的reac...
    99+
    2023-07-05
  • react如何用懒加载减少首屏加载时间
    目录使用安装如何在路由中使用?加载速度对比最近在写一个react-ant-admin的集成框架用于快速搭载中后台项目。其中遇到很多问题,最重要的应该是访问速度了。我就想 react ...
    99+
    2024-04-02
  • SQL Server中如何减少死锁
    SQL Server中如何减少死锁,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。  减少SQLServer死锁的方法有哪些  如事务1的线程T...
    99+
    2024-04-02
  • react如何改变数组中的某个元素
    这篇“react如何改变数组中的某个元素”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“react如何改变数组中的某个元素”文...
    99+
    2023-07-04
  • vue3中使用ref和emit来减少props的使用示例详解
    目录前言示例示例1示例2前言 在之前开发vue2项目中,props 属性在组件中经常使用来进行组件通信。现在在开发vue3项目的过程中,我们开发小组渐渐的减少props的使用,转而用...
    99+
    2024-04-02
  • js如何减少魔数
    这篇文章将为大家详细讲解有关js如何减少魔数,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。减少魔数例如,在某个文件的第 800 行,冒出来了一句:dialogHandler.showQuestionNai...
    99+
    2023-06-27
  • vue2.0中子组件如何改变props值并向父组件传值
    这篇文章主要介绍了vue2.0中子组件如何改变props值并向父组件传值,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。为什么我们会有修改 p...
    99+
    2024-04-02
  • MongoDB中如何减少索引碎片
    在MongoDB中,可以通过以下方法来减少索引碎片: 定期进行索引重建:定期对索引进行重建可以帮助减少索引碎片。在MongoDB...
    99+
    2024-04-19
    MongoDB
  • vue中如何修改props传进来的值
    众所周知,vue是单向数据流,一般我们也不会在子组件里面修改父组件传进来的值,但总有需要修改的时候。 前段时间一个项目中有遇到上述情况,假设我直接传进来一个list, 当时我直接在里...
    99+
    2022-12-08
    vue修改Props值 vue Props值
  • react如何实现点击时改变样式
    今天小编给大家分享一下react如何实现点击时改变样式的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。react实现点击时改变...
    99+
    2023-07-04
  • PHP7中的变量的严格模式:如何减少潜在的错误?
    PHP7 中引入了严格模式,该模式可以帮助开发者减少潜在的错误。本文将介绍什么是严格模式以及如何在 PHP7 中使用严格模式来减少错误。同时,将通过代码示例演示严格模式的应用。一、什么是严格模式?严格模式是 PHP7 中的一个特性,它可以帮...
    99+
    2023-10-22
    变量 PHP 严格模式
  • React在组件中如何监听redux中state状态的改变
    目录在组件中监听redux中state状态的改变解决方式React和redux的状态处理在组件中监听redux中state状态的改变 解决方式 1、在组件中引入store 2、在co...
    99+
    2022-11-13
    React组件 监听state的改变 监听redux中state改变
  • ubuntu如何减少开机时间
    ubuntu减少开机时间的方法:在终端输入“systemd-analyze blame”命令,查看启动服务占用的时间,然后慎重考虑是否禁用该服务。选择闭源附加驱动:software-properties-gtk。修改启动时间,在终端输入“s...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作