使用 useMemo 记忆 Context 值
将 Context 值对象包裹在 useMemo 中,避免消费者不必要地重新渲染。
使用 useMemo 记忆 Context 值 是 CoddyKit 上的免费 React Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
欢迎
在本课中,您将学习为什么必须使用 useMemo 缓存上下文值对象,以及如何正确设置依赖项以避免不必要的重新渲染。
对象引用问题
每当提供者组件重新渲染时,都会创建一个新的对象字面量 `{ ... }` 作为上下文值,即使其内容相同也是如此。由于引用发生了变化,所有消费者都会重新渲染。
// Every render creates a new object!
<UserCtx.Provider value={{ user, logout }}>
{children}
</UserCtx.Provider>使用 useMemo 修复
使用 useMemo 包装上下文值,这样当依赖项数组中的内容没有变化时,连续渲染之间会返回相同的对象引用。
const value = useMemo(
() => ({ user, logout }),
[user, logout]
);
<UserCtx.Provider value={value}>
{children}
</UserCtx.Provider>谨慎选择依赖项
将 useMemo 内使用的每个值都包含在依赖项数组中。缺少依赖项会导致值过时。请包含基本类型属性(字符串、数字)和稳定引用(使用 useCallback 包装的函数)。
使用 useCallback 保持函数稳定
函数值在每次渲染时都会改变引用。在将函数包含到 useMemo 的上下文值中之前,请先使用 useCallback 包装它们,以避免不必要的重新渲染。
const logout = useCallback(() => {
clearSession();
setUser(null);
}, []);
const value = useMemo(() => ({ user, logout }), [user, logout]);不需要缓存的情况
如果提供者组件从不重新渲染(例如,它位于组件树最顶层,并且其父组件从不变化),useMemo 只会增加开销而没有收益。只有在提供者自身会重新渲染时才进行缓存。
基本类型值本身已经稳定
如果上下文值是基本类型(字符串、数字、布尔值),您不需要(NOT)使用 useMemo——基本类型按值而不是按引用进行比较。`value={isDark}` 不会导致额外的重新渲染。
// No useMemo needed for primitives
<ThemeCtx.Provider value={isDark ? 'dark' : 'light'}>
{children}
</ThemeCtx.Provider>分析缓存的影响
使用 React DevTools Profiler 验证使用 useMemo 包装上下文值是否确实减少了重新渲染。分别记录使用前后的会话,以查看提交次数的差异。
嵌套的缓存上下文
嵌套多个上下文时,请分别缓存每个上下文。一个上下文的变化不会影响另一个上下文的缓存值。
提供者组件模式
将上下文、状态和缓存逻辑封装在专用的提供者组件中。导出一个用于使用上下文的自定义钩子。这是可复用上下文的规范模式。
export function UserProvider({ children }) {
const [user, setUser] = useState(null);
const logout = useCallback(() => setUser(null), []);
const value = useMemo(() => ({ user, logout }), [user, logout]);
return <UserCtx.Provider value={value}>{children}</UserCtx.Provider>;
}
export const useUser = () => useContext(UserCtx);快速检查
将上下文值对象包装在 useMemo 中的首要原因是什么?
回顾
使用正确的依赖项,通过 useMemo 包装上下文值对象。使用 useCallback 稳定函数值。基本类型不需要缓存。将上下文设置封装在带有自定义钩子的提供者组件中。
接下来
下一课:**上下文选择器模式**——您将实现一个选择器钩子,使消费者仅在上下文的特定切片发生变化时重新渲染。
常见问题解答
「使用 useMemo 记忆 Context 值」课时是免费的吗?
是的 — 「使用 useMemo 记忆 Context 值」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「使用 useMemo 记忆 Context 值」这节课中我会学到什么?
将 Context 值对象包裹在 useMemo 中,避免消费者不必要地重新渲染。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用 useMemo 记忆 Context 值」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 拆分 Context 以限制重新渲染
- 使用 useMemo 记忆 Context 值
- Context 选择器模式
- 何时不应使用 Context