举例useContext性能低下的样例,同时推荐用什么方法改进

发布时间 2024-01-10 18:49:16作者: 走,板砖去

在React中,useContext 是一种非常方便的全局状态管理工具,它可以让我们在组件之间共享状态,而不需要通过层层传递 props。然而,当我们在一个大型的 React 应用中过度使用 useContext 时,可能会遇到性能问题。这是因为当一个 context 的值改变时,所有使用这个 context 的组件都会重新渲染,即使这个组件并不需要那个改变的值。

举个例子,假设我们有一个全局的用户 context,它包含了用户的详细信息和一些设置:

const UserContext = React.createContext();

function App() {
  const [user, setUser] = useState({ name: 'John', age: 30, theme: 'dark' });

  return (
    <UserContext.Provider value={user}>
      <Profile />
      <Settings />
    </UserContext.Provider>
  );
}

function Profile() {
  const user = useContext(UserContext);
  
  return <h1>Welcome, {user.name}!</h1>;
}

function Settings() {
  const user = useContext(UserContext);
  
  return <div>Your current theme is: {user.theme}</div>;
}

在这个例子中,Profile 和 Settings 组件都使用了 UserContext。如果用户的主题改变了,Profile 组件也会重新渲染,即使它并不需要知道主题的信息。

一种改进方法是使用 React 的 useMemo useCallback 钩子来避免不必要的重新渲染。我们可以为每一个需要共享的状态创建一个单独的 context,然后使用 useMemo useCallback 来确保只有当这个状态改变时,使用这个状态的组件才会重新渲染:

const NameContext = React.createContext();
const ThemeContext = React.createContext();

function App() {
  const [user, setUser] = useState({ name: 'John', age: 30, theme: 'dark' });

  const userName = useMemo(() => user.name, [user.name]);
  const userTheme = useMemo(() => user.theme, [user.theme]);

  return (
    <NameContext.Provider value={userName}>
      <ThemeContext.Provider value={userTheme}>
        <Profile />
        <Settings />
      </ThemeContext.Provider>
    </NameContext.Provider>
  );
}

function Profile() {
  const name = useContext(NameContext);
  
  return <h1>Welcome, {name}!</h1>;
}

function Settings() {
  const theme = useContext(ThemeContext);
  
  return <div>Your current theme is: {theme}</div>;
}