返回

搞定 useContext 与 useReducer,组件之间共享复杂状态

前端

在上一篇文章中,我们提到使用 useReducer 可以帮助我们集中式地处理复杂的 state 管理。但在实际开发中,我们的页面往往很复杂,通常拆分成多层多个组件。这种情况下,如何让子组件触发这些 state 变化呢?

1. useContext 与 useReducer 的基本原理

  1. useContext:

    • useContext 是 React 提供的一个用于在组件树中共享状态的高阶 Hook。
    • 通过调用 React.createContext 创建一个 context,并将此 context 的值传递给所有子组件。
    • 在子组件中,可以使用 useContext hook 访问 context 的值。
  2. useReducer:

    • useReducer 是 React 提供的另一个用于状态管理的高阶 Hook。
    • 通过调用 useReducer 创建一个 reducer,该 reducer 是一个纯函数,用于根据当前 state 和一个 action 来计算新的 state。
    • 在组件中,可以使用 useReducer hook 来访问 reducer 和 state,并通过 dispatch 方法触发 reducer 来改变 state。

2. useContext 与 useReducer 的组合使用

  1. 使用 useContext 在组件树中共享一个 context,其中包含 useReducer 的 state 和 dispatch 方法。
  2. 在子组件中,使用 useContext hook 访问 context,从而获取 state 和 dispatch 方法。
  3. 在子组件中,通过调用 dispatch 方法来触发 reducer,从而改变 state。

3. 示例代码

// context.js
import { createContext, useState } from "react";

const MyContext = createContext();

const MyProvider = ({ children }) => {
  const [state, dispatch] = useState({ count: 0 });

  return (
    <MyContext.Provider value={{ state, dispatch }}>
      {children}
    </MyContext.Provider>
  );
};

export { MyContext, MyProvider };
// parent.js
import React, { useContext } from "react";
import { MyContext } from "./context";

const Parent = () => {
  const { state, dispatch } = useContext(MyContext);

  return (
    <div>
      <h1>Parent</h1>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>
        Increment
      </button>
      <Child />
    </div>
  );
};

export default Parent;
// child.js
import React, { useContext } from "react";
import { MyContext } from "./context";

const Child = () => {
  const { state, dispatch } = useContext(MyContext);

  return (
    <div>
      <h1>Child</h1>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "decrement" })}>
        Decrement
      </button>
    </div>
  );
};

export default Child;

在上面的示例中,我们创建了一个 context,其中包含 useReducer 的 state 和 dispatch 方法。然后,我们在父组件中使用 MyProvider 包装子组件,并在子组件中使用 useContext hook 来访问 context,从而获取 state 和 dispatch 方法。最后,在子组件中,通过调用 dispatch 方法来触发 reducer,从而改变 state。

4. 总结

  1. useReduceruseContext 都是 React 提供的高阶 Hook,用于管理组件状态。
  2. useContext 用于在组件树中共享状态,而 useReducer 用于集中式地处理复杂的 state 管理。
  3. useContextuseReducer 结合使用,可以让我们在复杂组件中轻松地共享和改变状态。