原文永久链接: 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项目代码层面的东西,如果你需要做一些优化方面的工作,也可以从打包、编译入手。

ps: 顺便推一下自己的个人公众号:Yopai,有兴趣的可以关注,每周不定期更新,分享可以增加世界的快乐

聊一聊,React开发中应该规避的点的更多相关文章

  1. 在React开发中遇到的问题——数组引用赋值

    在React开发中遇到了一个问题: 需求是在一个选择组件中选择数据mydata数组,确定后将mydata数组返回到父组件,再次打开该选择组件时,从父组件获取之前选择的数据mydata并显示为已选择. ...

  2. React开发中react-route-dom使用BrowserRouter部署到服务器上刷新时报404的问题

    React项目部署中遇到的问题 react开发中react-route使用BrowserRoute路径在iis服务器上刷新时报404的问题 解决:在发布的项目根目录添加web.config配置文件 在 ...

  3. react 开发中的问题简记

    1.什么时候用props 什么时候用state ? 不能使用props:当页面组件存在URL跳转问题时候,原因:若单独刷新,他会报错,拿不到前面的数据: 使用props场景:当组件为页面组件的一部分即 ...

  4. React 开发中面临的九个重要抉择

    抉择系列:在技术开发的过程中我们会面临着各种各样的抉择,我们在不同情境下该如何选择恰当的技术,这是本系列文章想要解决的问题. 在 React 开发的过程中我们常常会遇到一些抉择,下面我将选取其中一些个 ...

  5. react开发中如何使用require.ensure加载es6风格的组件

    其实用的babel,在浏览器端就应该可以加载,之前少了个default: require.ensure([],(require) => { let A = require('./a.js').d ...

  6. react开发中的小细节

    目前开始使用react余遇到的问题还不是很多,但还是希望总结一下. react中的属性prop: 在react中组件的父子组件的通信是基于prop的,当然对于底层的东西不是特别了解,但可以说一说它的基 ...

  7. 21个React开发神器

    摘要: React开发神器. 原文:22 Miraculous Tools for React Developers in 2019 译者:前端小智 下列工具中的重要性与排序无关. 1.Webpack ...

  8. React在开发中的常用结构以及功能详解

    一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: impo ...

  9. 规避 React 组件中的 bind(this)

    React 组件中处理 onClick 类似事件绑定的时候,是需要显式给处理器绑定上下文(context)的,这一度使代码变得冗余和难看. 请看如下的示例: class App extends Com ...

随机推荐

  1. Web前端开发工具和环境清单

    初级 浏览器 Google Chrome 75.0.3770.100www.google.cn/intl/zh-CN/chrome初级 移动端模拟器 Genymotion 6.0.6www.genym ...

  2. c博客作业01——顺序 分支结构

    本章学习总结 1.1 学习内容总结 ·学习switch分支的使用,switch后加括号(),括号内填一个变量或字符 如 switch (a) { case 2: case 3: default: } ...

  3. Java-Long类型精度丢失问题

    问题 今天碰到一个问题,后端需要返回给前端Long类型的id,前端收到的id会发生精度丢失. 测试代码:后端返回的值为344739147160346624 但是前端获取的值为: 解决办法 将返回的值转 ...

  4. jmeter待解决55大问题

    客户交付一个性能测试项目,阐述实施流程. 解释5个常用的性能指标的名称与具体含义. 写出5个jmeter中常用函数,并对其中2个举例说明用法. 简述jmeter的工作原理? 什么是集合点?设置集合点有 ...

  5. POI报表打印

    一.Excel报表(POI) 1.需求说明 在企业级应用开发中,Excel报表是一种最常见的报表需求.Excel报表开发一般分为两种形式: 1.为了方便操作,基于Excel的报表批量上传数据 2.通过 ...

  6. how does SELECT TOP works when no order by is specified?

    how does SELECT TOP works when no order by is specified? There is no guarantee which two rows you ge ...

  7. 关于高负载服务器Kernel的ipv4的TCP参数说明及优化

    net.ipv4.tcp_mem 内核分配给TCP连接的内存,单位是Page,1 Page = 4096 Bytes,可用命令查看: #getconf PAGESIZE 4096 net.ipv4.t ...

  8. Cache busting

    Cache busting https://www.keycdn.com/support/what-is-cache-busting https://curtistimson.co.uk/post/f ...

  9. 在evernote中如何使序号正常连续?

    答: 在二级内容之前按Shift + Enter键,再次换行即可序号正常,示例如下: 1. 第一行(在此处按下Shift+Enter键) 第一行第一列(在此处按下Shift+Enter键) 第一行第二 ...

  10. mac安装MySQLdb:IndexError: string index out of range

    使用mac安装MySQLdb的时候出现string index out of range 大概的错误是这样的: 然后尝试手动安装,我下载了包后,依然出现这个错误. 于是百度了下: https://ww ...