0Pricing
React Academy · 课时

拆分 Context 以限制重新渲染

将频繁变化的值与稳定值分别放入不同的 Context 中。

拆分 Context 以限制重新渲染 是 CoddyKit 上的免费 React Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

欢迎

在本课中,您将学习如何将 React 上下文拆分到不同的提供者中,以便仅有部分上下文值发生变化时,尽量减少重新渲染。

上下文导致的重新渲染问题

调用 useContext(MyCtx) 的每个组件都会在上下文值的任何(ANY)部分发生变化时重新渲染——即使它使用的部分没有变化。单个大型上下文可能导致许多不必要的重新渲染。

按更新频率拆分

将频繁变化的值与很少变化的值分开。将每组值放入自己的上下文中。消费者只订阅它们需要的上下文。
const ThemeCtx = createContext('light');
const UserCtx = createContext(null);
// theme changes rarely; user changes on login/logout — same frequency is fine
// but notifCount changes every second — split it out!

分离数据上下文与分发上下文

一种常见模式是将一个上下文拆分为状态数据上下文(每次变化都会重新渲染)和另一个分发函数/设置函数上下文(稳定,不会使消费者重新渲染)。只使用分发函数的消费者不会因数据变化而重新渲染。
const CountCtx = createContext(0);
const SetCountCtx = createContext(() => {});

function Provider({ children }) {
  const [count, setCount] = useState(0);
  return (
    <CountCtx.Provider value={count}>
      <SetCountCtx.Provider value={setCount}>
        {children}
      </SetCountCtx.Provider>
    </CountCtx.Provider>
  );
}

缓存分发上下文

useState 返回的设置函数是稳定的(每次渲染都具有相同引用),因此分发上下文的值不会变化。但是,如果您计算出一个操作对象,请使用 useMemo 将其包装起来。
const actions = useMemo(() => ({
  increment: () => setCount(c => c + 1),
  reset: () => setCount(0),
}), []); // stable — empty deps

嵌套提供者

在组件树中嵌套多个提供者。消费者只导入并使用所需的特定上下文,从而保持较小的订阅范围。
function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <NotificationsProvider>
          <Router />
        </NotificationsProvider>
      </ThemeProvider>
    </AuthProvider>
  );
}

拆分前进行性能分析

在拆分上下文之前,始终使用 React DevTools 进行性能分析。只有在不必要的重新渲染代价很高时,它们才会成为问题。不要过度设计那些重新渲染开销很小的上下文。

拆分上下文的权衡

更多上下文意味着组件树中有更多提供者。这会增加认知负担。只有在性能分析显示存在性能问题时才进行拆分,不要提前拆分。

与 React.memo 结合使用

即使只有一个上下文,将代价高昂的子组件包装在 React.memo 中,也意味着它们只会在属性发生变化时重新渲染,而不会因上下文变化而重新渲染。这可能是比拆分上下文更简单的替代方案。
const ExpensiveChild = React.memo(function({ label }) {
  return <div>{label}</div>;
}); // won't re-render on context change if label hasn't changed

useReducer + 上下文

将 useReducer 与上下文结合起来管理复杂状态。将状态存储在一个上下文中,将分发函数存储在另一个上下文中。分发函数是稳定的;状态会在每次操作后更新。

快速检查

为什么将状态和分发函数拆分到不同的上下文中可以提升性能?

回顾

根据更新频率拆分上下文:将频繁变化的状态放在一个上下文中,将稳定的分发函数/设置函数放在另一个上下文中。先进行性能分析,只在确有必要时拆分,并考虑将 React.memo 作为更简单的替代方案。

接下来

下一课:**使用 useMemo 缓存上下文值**——您将使用 useMemo 包装上下文值对象,使消费者不会因未发生变化的数据而重新渲染。

常见问题解答

「拆分 Context 以限制重新渲染」课时是免费的吗?

是的 — 「拆分 Context 以限制重新渲染」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「拆分 Context 以限制重新渲染」这节课中我会学到什么?

将频繁变化的值与稳定值分别放入不同的 Context 中。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「拆分 Context 以限制重新渲染」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

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