React | React组件化开发(二)

✨ 个人主页:CoderHing

🖥️ React .js专栏:React .js React组件化开发(二)
🙋‍♂️ 个人简介:一个不甘平庸的平凡人🍬

💫 系列专栏:吊打面试官系列  16天学会Vue  11天学会React  Node专栏

🍀 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️

👉 你的一键三连是我更新的最大动力!❤️

❤️ 本文约 6470 字,预计阅读需要 20 分钟 ❤️


目录

一、React性能优化SCU

React更新机制

React更新流程

keys的优化

render函数被调用

shouldComponentUpdate

PureComponent

shallowEqual方法

高阶组件memo

不可变数据的力量

二、获取DOM方式refs

如何使用ref

ref的类型

三、受控和非受控组件

认识受控组件

受控组件的基本演练

受控组件的其他演练

非受控组件(不推荐使用)

四、React的高阶组件

认识高阶函数(Hooks后用的较少)

高阶组件的定义

开发中:应用一:props的加强

开发中:应用二:渲染判断鉴权

开发中:应用三:生命周期劫持

高阶函数的意义

ref的转发

五、portals和fragment

portals的使用

fragment(片段)的使用

六、StrictMode严格模式

StrictMode

严格模式检查的是什么?


一、React性能优化SCU

React更新机制

  • React渲染流程:

    • 在render函数中返回一个jsx

    • jsx创建出来对应的React.createElement

    • 这些element最终会形成一个树结构(对应的话就是虚拟DOM)

    • 最后React会根据虚拟DOM去渲染出来一个真实DOM

  • React更新流程:

    • 当前props/state发生改变

    • render函数重新执行

    • 之后产生一棵新的DOM树(新的树结构)

    • 在新旧树结构中进行diff算法来对比差异

    • 之后计算出差异的点进行一系列的更新

    • 最后把需要更新的地方更新到真实的DOM中

React更新流程

  • React在props或state发生改变时,会调用React的render方法,会创建出一棵不同的树.

  • React需要基于这两棵不同的树之间的差异来判断如何有效的更新UI:

    • 如果一棵树参考另外一棵树进行完全比较更新,那么即使是最先进的算法(算法的复杂程度为O(n²)),其中n是树中元素的数量

    • 如果React中使用了该算法,那么展示1000个元素所需要执行的计算量将在亿的量级范围内.

    • 这个开销很大,那么React更新性能将会变得十分低效.

  • React对这个算法进行了优化,将其优化成了O(n),如何优化的呢?

    • 同层节点之间相互比较,不会跨节点比较

    • 不同类型的节点,产生不同的树结构

    • 开发中,可以通过key来指定哪些节点在不同的渲染下保持稳定.

keys的优化

  • 我们在之前遍历列表时,总是会提示一个警告,让我们加入一个key属性:

  • 方式一:在最后位置插入数据

    • 这种情况有没有key其实意义并不是很大

  • 方式二:在前面插入数据

    • 这种情况在没有key的情况下,所有的li都会进行修改

  • 当子元素(li)拥有key时,React使用key来匹配原有树上的子元素以及最新树上的子元素

    • 在这种场景下,key为111和222的元素仅仅进行了位移,不需要进行任何的修改

    • 将key为333的元素插入到最前面的位置即可

  • key的注意事项

    • key应该是唯一的

    • key不要使用随机数(随机数会在下一次render时,重新生成一个新数)

    • 使用index作为key,对性能是没有优化的

render函数被调用

  • 嵌套案例:

    • 在App中,我们增加了一个计数器的代码

    • 当点击+1时,hUI重新调用App的render函数

    • 而当App的render函数被调用时,所有的子组件的render函数都会被重新调用

  • 那么,在之后的开发中,我们只是修改了App中的数据,是,所有的组件都需要重新render,进行diff算法,性能肯定非常低:

    • 事实上,很多的组件是没有必要去重新render的

    • 它们调用render应该有一个前提,就是依赖的数据(state,porps)发生改变,再去调用render方法;

  • 那么怎么来控制render方法是否被调用?

    • 通过shouldComponentUpdate方法即可

shouldComponentUpdate

  • React提供了一个生命周期方法 shouldComponentUpdate(简称:SCU)这个方法接收参数,并且需要有返回值:

  • 该方法有两个参数:

    • nextProps => 修改之后,新的props属性

    • nextState => 修改之后,新的state属性

  • 该方法返回值是一个boolean类型:

    • 返回值为true时,就需要调用render方法

    • false则不需要调用

    • 默认返回是true,也就是只要state/props发生改变,就会调用

  • 比如我们在App中增加一个message属性:

    • jsx中并没有依赖message,那么她的改变不应该引起重新渲染

    • 但是因为render监听到了state中的改变,就会重新render,所以最后render方法还是被调用了.

PureComponent

  • 如果所有的类都需要手动去实现 shouldComponentUpdate,那么会给开发带来很多的重复工作量

    • 我们设想一下shouldComponentUpdate中的各种判断目的是什么?

    • props/state中的数据是否发生了改变,来决定shouldComponentUpdate返回true/false

  • 事实上React已经考虑到了这一点,所以React已经默认帮我们实现好了,那么如何实现的?

    • 将class继承自PureComponent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coderHing[专注前端]

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值