语法
- 传统 Provider 和 Consumer:使用
<Provider>
组件包裹需要共享数据的组件树,并通过 value
属性传递数据。消费数据时,需要在组件树中使用 <Consumer>
组件,以函数作为子元素的方式获取 Context 数据,例如:
<Provider value={data}>
<App>
<Consumer>
{value => <div>{value}</div>}
</Consumer>
</App>
</Provider>
- 新 Context API:使用
useContext
钩子函数在函数组件中更简洁地消费 Context 数据。创建 Context 时语法基本不变,但是消费时更加直观。例如:
const MyContext = createContext();
function MyComponent() {
const value = useContext(MyContext);
return <div>{value}</div>;
}
功能
- 传统 Provider 和 Consumer:Consumer 必须是 Provider 的后代组件才能获取数据,数据传递相对比较直观但嵌套层次较深时代码结构会变得复杂。
- 新 Context API:
useContext
可以在组件树的任何位置获取 Context 数据,只要该组件在 Context 的 Provider 包裹范围内,提高了代码的灵活性,同时也方便在自定义钩子函数中使用 Context。
性能
- 传统 Provider 和 Consumer:每次 Provider 的
value
属性变化时,所有 Consumer 组件都会重新渲染,即使其依赖的数据并未真正改变,这可能导致不必要的性能开销。
- 新 Context API:结合 React.memo 或
shouldComponentUpdate
可以更细粒度地控制组件的重新渲染。当使用 useContext
时,只有当 Context 的值发生变化,且组件本身依赖该 Context 数据时才会重新渲染,一定程度上提升了性能。
使用场景
- 继续使用 Provider 和 Consumer 的场景:
- 在类组件为主的项目中,由于类组件无法使用钩子函数,Provider 和 Consumer 方式是唯一选择来实现 Context 数据共享。
- 对于需要严格控制数据传递层级,确保数据传递路径清晰的场景,Provider 和 Consumer 的嵌套结构能直观地展示数据流向。
- 切换到新 Context API 的场景:
- 在以函数组件为主的项目中,
useContext
钩子函数提供了更简洁的代码写法,使代码逻辑更清晰,易于维护。
- 当需要在自定义钩子函数中使用 Context 数据时,新 Context API 配合自定义钩子能更好地复用逻辑,提高开发效率。同时,在性能敏感的场景下,新 API 更细粒度的渲染控制可以有效优化性能。