组件通信
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,消费context的FiberNode会提升更新优先级。对于类组件的FiberNode,会forceUpdate。接下来所有消费的FiberNode,都会执行beginWorkContext订阅流程:Consumer组件会内部调用readContext,readContext会把FiberNode上的dependencies属性和context建立起关联(useContext)
多个 Provider
React 用栈的形式维护多个 Provider,确保组件取得的是最近的 Priovider 的 value
- 在
performUnitOfWork中会调用updateContextProvider,该函数会调用pushProvider将cursor.current放到栈顶,然后新的 value 放到 cursor.current 上。 - react render 过程遇到
context.consumer的时候,会去读取这个cursor.current的值,传值到Consumer - 最后调用
completeUnitOfWork的时候又会去popPrivider,将栈顶的 value 恢复到cursor.current。所以永远取得的是最近的Priovider的 value
Context 穿透问题,如何优化?
它是可以穿透 React.memo 或者 shouldComponentUpdate 的比对的,也就是说,一旦 Context 的 Value 变动,所有依赖该 Context 的组件会全部 forceUpdate
优化方法:
- 细粒度订阅
- 借助顶层组件 props 共享状态给子组件
- 用 mobx
react-redux 工作原理?
- 通过 Provider 把 redux 中的 store 注入到组件中