0Pricing
React Academy · 课时

使用 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 拆分 Context 以限制重新渲染
  2. 使用 useMemo 记忆 Context 值
  3. Context 选择器模式
  4. 何时不应使用 Context
← 返回 React Academy