Skip to main content

React

生命周期

参考 https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

>= 16.4

为什么在 16.4 版本之后对生命周期进行了大调整?比如废弃了 componentWillMount/componentWillReceiveProps/componentWillUpdate

父子组件生命周期的执行顺序

挂载时,子组件的挂载钩子先被触发;卸载时,子组件的卸载钩子后被触发

babel 插件

  • @babel/babel-preset-react-app(<17)
  • react/jsx-runtime

介绍新的 jsx 转换-官方

老版本的 React 中,为什么写 jsx 的文件要默认引入 React?

组件分类

  • 类组件
  • 函数组件

对于类组件来说,底层只需要实例化一次,实例中保存了组件的 state 等状态。对于每一次更新只需要调用 render 方法以及对应的生命周期就可以了。但是在函数组件中,每一次更新都是一次新的函数执行,一次函数组件的更新,里面的变量会重新声明

React 高阶组件是什么,和普通组件有什么区别,适用什么场景

高阶组件(HOC)就是一个函数, 且该函数接受一个组件作为参数, 并返回一个新的组件

优点

  • 逻辑复用、不影响被包裹组件的内部逻辑

缺点

  • 组件多层嵌套, 增加复杂度
  • hoc 传递给被包裹组件的 props 容易和被包裹后的组件重名,进而被覆盖,而且不清楚 props 来源与哪个高阶组件
  • ref 隔断问题,React.forwardRef 来解决【WIP】

参考 https://juejin.cn/post/6844903782355042312

react18

一文解读 React 17 与 React 18 的更新变化

三种模式

  • legacy
  • blocking
  • concurrent

https://17.reactjs.org/docs/concurrent-mode-adoption.html#feature-comparison

新增特性

  • 自动批量更新
  • 订阅外部数据源
  • transition
  • Offscreen

react18 自动批量更新是如何实现的?

根据优先级 lane,第一个 setState 发起调度更新,后续同等优先级的会跳过调度更新

参考 https://github.com/facebook/react/issues/11527

异常处理

React 中可以定义 ErrorBounding 组件来帮助我们捕获异常(componentDidCatch 或 getDerivedStateFromError),实际上就是子组件在 reconciler 期间,利用 try catch 来捕获报错的组件,即如果遇到错误,则会就被 catch 到,然后从该报错的组件往上找错误边界,只要父组件是类组件,且有实例属性 componentDidCatch 或静态属性 getDerivedStateFromError,那么就判定为错误边界,同时在上述两个方法中可以修改 state,从而渲染出备用的 ui,而不至于直接让页面白屏

不过有局限性,以下是无法处理的情况:

  • 事件处理函数,如 onClick,onMouseEnter
  • 异步代码,如 requestAnimationFrame,setTimeout,promise
  • 服务端渲染
  • ErrorBoundary 组件本身的错误

创建一个基础的 ErrorBounding 组件

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}

参考

优化手段

减少组件重渲染

  • memo/shouldComponentUpdate
  • useMemo/useCallback
  • 批量更新ReactDOM.unstable_batchedUpdates(react18 之前适用,react18 已有自动批量更新)

减少节点

  • 惰性渲染(懒加载)
  • 虚拟列表

降低渲染计算量

  • 缓存结果或对象 useMemo/useCallback
  • webWorker

精细化渲染

  • 参考 mobx 和 vue
  • 不滥用 Context

时间分片