React相关总结

102 阅读6分钟

1. useMemo 和 useCallback

接收的参数都是一样,第一个参数为回调 第二个参数为要依赖的数据

  • 共同作用: 仅仅 依赖数据 发生变化, 才会重新计算结果,也就是起到缓存的作用。
  • 两者区别:
    • useMemo 计算结果是 return 回来的值, 主要用于 缓存计算结果的值 ,应用场景如: 需要 计算的状态

    • useCallback 计算结果是 函数, 主要用于 缓存函数,应用场景如: 需要缓存的函数,因为函数式组件每次任何一个 state 的变化 整个组件 都会被重新刷新,一些函数是没有必要被重新刷新的,此时就应该缓存起来,提高性能,和减少资源浪费。 注意: 不要滥用会造成性能浪费,react中减少render就能提高性能,所以这个仅仅只针对缓存能减少重复渲染时使用和缓存计算结果。

2.react源码解密

  • react15架构是同步执行,无法中断更新,更无法切片式处理同步任务,ReconcilerRenderer协调和渲染是同步执行的
  • react16架构通过控制schecher和reconciler在内存中进行,renderer只有在schecher和reconciler全部完成后进行,避免react15中断出现不完全更新的情况
  • react16之前使用合成事件,代理到document,冒泡到document之前会执行react捕获和冒泡的功能 17以后委托给root,所以document捕获后开始捕获react相关,react冒泡是在document之前进行.16到17更改了事件委托,更改了事件池,16前react阻止冒泡用stopImmediatePropagatiin
  • React16相较于React15架构增加调度器,使用Scheduler替换原有的方法requestIdleCallback,弥补浏览器兼容和多个tabs切换触发频率不稳定的问题
  • react16不使用Generator实现可中断式异步切片的原因:Generator上下文依赖性极强,无法完全切割
  • 双缓存:在内存中绘制当前帧动画,绘制完毕后直接用当前帧替换上一帧画面,由于省去了两帧替换间的计算时间,不会出现从白屏到出现画面的闪烁情况
  • fiberRootNode是整个应用的根节点,rootFiber<App/>所在组件树的根节点。
  • 协调阶段实际式render阶段,Renderer阶段在架构上已经进入了commit阶段
-   `Reconciler`工作的阶段被称为`render`阶段。因为在该阶段会调用组件的`render`方法。
-   `Renderer`工作的阶段被称为`commit`阶段。就像你完成一个需求的编码后执行`git commit`提交代码。`commit`阶段会把`render`阶段提交的信息渲染在页面上。
-   `render``commit`阶段统称为`work`,即`React`在工作中。相对应的,如果任务正在`Scheduler`内调度,就不属于`work`
  • Fiber
浏览器绘制页面和执行js是互斥的,浏览器渲染是1s渲染60帧,即116.6秒
如果出现1花费时间超过16.6就会出现卡顿react fiber就是解决了这个问题
将任务切分一块块,大概用掉空闲帧中的空闲时间5ms用来进行操作
react使用虚拟dom实现跨平台渲染,使用异步可中断和增量更新实现快速响应
  • Diff算法
是对比老的Fiber链表和新的jsx数组,生成新的Fiber链表的过程
单节点索引新的,如果有改变,则应用新的,老的视为删除标记
多节点,分两步,1更新2新增删除等
如果遇到key不同则进行第二轮循环
  • 名词解释
Child 首个子节点 Sibling 兄弟节点 Return 父节点

Antd

antd表格属性align,TypeScript强类型报错

1.columns=[{align:'left'} as ColumnProps]
2.columns: [
  {
    title: 'xxx',
    dataIndex: 'xxx',
    align: 'left' as 'left', // cast fixed
  },
]

小切片

  • 单向数据流:子组件不能改变父组件的state中数据,会报错。
  • 不能用class会和class类混淆
  • Htmlfor代替for使用,避免和js的for冲突
  • 函数式编程好处:每个函数代码比较清晰;对于代码测试比较方便,便于前端自动化测试
  • 父组件向子组件传值 PropTypes类型检验;defaultProps设定默认值
  • ref可以对于标签赋值获取,ref=(input)=>{this.input=input}
  • 生命周期:
componentWillMount render componentDidMount

componentWillReceiveProps:组件第一次存在dom中,函数不会执行。如果已经存在dom中,函数才会执行 
性能优化: 
shouldComponentUpdate(nextProps,nextState){ 
if(nexrProps.content!==this.props.content){ 
return true 
}else{ 
return false 
} }:
return true会继续执行下面勾了,返回false就不会继续执行 
componentWillUpdate 
render 
componentDidUpdate
componentWillUnmount
  • react-transition-group动画
  • useState不能用于条件判断中
  • Jsx映射虚拟dom原理
jsx返回的就是一个react.creactElement"react"元素,
jsx就是creactElement的语法糖,通过crea ctElement对参数进行拆解,
发起ReactElement调用生成虚拟dom对象

类组件和函数组件

  • 首先类组件需要继承,函数组件不需要,
  • 类组件可以访问生命周期的方法,函数组件不可以
  • 类组件可以得到实例化的this,函数组件没有,函数组件可以屏蔽this问题,没有状态组件,所以更方便并发渲染
  • 类组件容易嵌套地狱,hooks可以无需要改变组件结构而复用组件状态
  • 类组件是面向对象的方式,需要实例化使用,函数组件可以直接使用,return回来即可使用
  • 类组件需要创建实例,无法立即销毁,会占用内存,函数组件不会
  • 函数组件具有值捕获特性,会过去当前渲染值,而不是最新值,函数组件更方便单元测试
  • 函数组件使用usestate和useEffect和类组件不同
  • 类组件跳过更新,shouldComponentUpdate,或者使用浅比较 函数组件使用usememo 判断是类组件还是函数组件 React对象上有creatElement和Component,component原型上如果有isReactComponent属性,则说明是类组件,否则为函数组件
  • JSX
可以将样式,js语法放一起,实现高内聚
不引入特殊的语法,简单明了
react虚拟dom,越过兼容性,是一个js对象,避免用户操作真实dom,
同时避免了xss攻击,兼容性好也可以实现跨平台应用,可以实现差异化更新
虚拟dom,并不是一直快,首次需要构建虚拟dom,并不快,
更新的时候会差异性更新,更新起来更快

BUG

  • NPM二次封装的pro组件,install到umi架构的项目中会出现表格列错乱 讲package中的npm包卸载就可以解决