Skip to main content

组件通信

React 组件通信主要有父子通信 props/callback、React Context 和 Redux/Mobx

props/callback

常规的父子组件通信

props 需要确保只读,保证数据单向流动,但在 react18 中修改 props 的引用属性表现为不报错,可以修改成功,但直接赋值覆盖或者新增删除值均无效

// props: { data: {} }
// Object.getOwnPropertyDescriptors(props)
data: {
value: Object;
writable: false;
enumerable: true;
configurable: false;
}

因此 props 应该是对 fiber.memorizedProps 做了类似的约束配置

Context

通过 createContext 创建一个 context

  • Provider 传递流程:Provider 组件在 React render 过程中,会遍历子代 FiberNode,消费 contextFiberNode 会提升更新优先级。对于类组件的 FiberNode,会 forceUpdate。接下来所有消费的 FiberNode,都会执行 beginWork
  • Context 订阅流程:Consumer 组件会内部调用 readContextreadContext 会把 FiberNode 上的 dependencies 属性和 context 建立起关联(useContext

多个 Provider

React 用栈的形式维护多个 Provider,确保组件取得的是最近的 Priovider 的 value

  1. performUnitOfWork 中会调用 updateContextProvider,该函数会调用 pushProvidercursor.current 放到栈顶,然后新的 value 放到 cursor.current 上。
  2. react render 过程遇到 context.consumer 的时候,会去读取这个 cursor.current 的值,传值到 Consumer
  3. 最后调用 completeUnitOfWork 的时候又会去 popPrivider,将栈顶的 value 恢复到 cursor.current。所以永远取得的是最近的 Priovider 的 value

Context 穿透问题,如何优化?

它是可以穿透 React.memo 或者 shouldComponentUpdate 的比对的,也就是说,一旦 Context 的 Value 变动,所有依赖该 Context 的组件会全部 forceUpdate

优化方法:

  • 细粒度订阅
  • 借助顶层组件 props 共享状态给子组件
  • 用 mobx

react-redux 工作原理?

  • 通过 Provider 把 redux 中的 store 注入到组件中

参考