Context 选择器模式
实现一个简单的选择器钩子,仅在 Context 的某个切片发生变化时重新渲染。
第 3 / 4 课13 个步骤
Context 选择器模式 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
欢迎
在本课中,您将实现一个上下文选择器钩子,使组件只订阅上下文状态的一个切片,从而在上下文中不相关的部分发生变化时避免重新渲染。
选择器问题
useContext 会在上下文的任何(ANY)部分发生变化时重新渲染。如果组件只需要用户姓名,而上下文还包含通知列表,那么添加通知会导致姓名组件不必要地重新渲染。
什么是选择器
选择器是从较大的状态对象中提取特定状态片段的函数:`state => state.user.name`。选择器钩子会订阅上下文,但只有选中的值发生变化时才会触发重新渲染。
简单的选择器钩子
构建一个 useSelector 钩子来读取上下文,并使用选择器的结果作为依赖进行 useMemo 包装。组件只会在选中的值发生变化时重新渲染。
function useAppSelector(selector) {
const state = useContext(AppCtx);
return useMemo(() => selector(state), [state, selector]);
}
// Consumer only re-renders when user.name changes
const name = useAppSelector(s => s.user.name);浅比较检查
即使选择器返回的对象或数组内容相同,只要每次调用时引用都是新的,使用选择器的 useMemo 仍会导致重新渲染(例如 `s => s.items.filter(...)`)。请使用浅比较来避免内容相同时的重新渲染。
import { useRef } from 'react';
function useSelector(selector) {
const state = useContext(AppCtx);
const selected = selector(state);
const ref = useRef(selected);
if (!shallowEqual(ref.current, selected)) {
ref.current = selected;
}
return ref.current;
}use-context-selector 库
在生产环境中,**use-context-selector** 库提供了带有高效订阅和相等性检查的 useContextSelector 钩子,无需外部状态管理器。
import { useContextSelector } from 'use-context-selector';
const name = useContextSelector(AppCtx, s => s.user.name);将 Zustand 作为原生支持选择器的解决方案
Zustand 的 `useStore(selector)` 钩子内置了选择器支持,并开箱即用地支持浅比较,因此非常适合大型状态树中需要细粒度订阅的场景。
const name = useAppStore(state => state.user.name);选择器何时属于过度设计
如果上下文更新不频繁,且消费者重新渲染的开销很小,选择器只会增加复杂度而没有可测量的收益。请先进行性能分析——始终根据证据进行优化。
缓存选择器函数
如果您在组件主体中内联创建选择器,那么每次渲染都会得到新的函数引用,可能破坏缓存。请在组件外定义选择器,或使用 useCallback。
// Outside component — stable reference
const selectName = s => s.user.name;
function Profile() {
const name = useAppSelector(selectName);
return <p>{name}</p>;
}派生选择器
通过在一个选择器中调用另一个选择器来组合选择器。派生选择器根据基础选择器计算值,使业务逻辑保持在组件之外。
const selectFullName = s => s.user.firstName + ' ' + s.user.lastName;快速检查
与 useContextSelector 或 useMemo 一起使用时,为什么应在组件主体外定义选择器函数?
回顾
选择器提取上下文状态的一个切片,并在不相关部分发生变化时避免重新渲染。在组件外定义选择器,以保持引用稳定。生产环境中,请使用 use-context-selector 或 Zustand 获得完善的选择器支持。
接下来
下一课:**何时不应使用上下文**——您将学习如何识别 prop 传递、组合或状态管理器比 Context 更合适、更简单的情况。
免费开始
用 AI 导师学习 React — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 88
- 课程
- 324
常见问题解答
「Context 选择器模式」课时是免费的吗?
是的 — 「Context 选择器模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「Context 选择器模式」这节课中我会学到什么?
实现一个简单的选择器钩子,仅在 Context 的某个切片发生变化时重新渲染。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「Context 选择器模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。