useContext 不转发来自 useReducer 的调度函数

useContext does not forward dispatch function from useReducer

我尽量不使用 Redux。所以我坚持使用 useContext 结合 useReducer 进行全局状态管理。我的问题:我无法使用分派更新子组件的状态。

让我更详细地解释一下。我的上下文文件非常简单:

import React, { createContext } from "react";

const ActivateContext = createContext();

export default ActivateContext;

我将其导入 App.js 并将其环绕在我的导航中的根组件周围:

import React, { useState, useReducer } from "react";
import Navigation from "./Navigation";
import ActivateContext from "./store/activate-context";

const Reducer = (state, action) => {
  if (action.type === "ACTIVATE_IT") return true;
};

export default function App() {

let initialState = false;
  const [state, dispatch] = useReducer(Reducer, initialState);

  return (
    <Provider store={store}>
      <ActivateContext.Provider  value={{activeStatus: state, activeDispatch: dispatch}}>
        <Navigation />
      </ActivateContext.Provider>
    </Provider>
  );

然后我在名为“Child”的子组件中导入“ActivateContext”。我将所有内容保存在常量“激活”中。然后我在名为“access”的道具中使用“activated”:

import React, {useContext} from "react";
import ActivateContext from "../../../store/activate-context";

function Child (props) {
  
const activated = useContext(ActivateContext);

   <MightComponent title="So Amazing" access={activated} />

我试图向组件“Child”添加一个按钮来更改 App.js 中的状态,但没有任何反应:

   <TouchableOpacity
            onClick={() => ActivateContext.activeDispatch("ACTIVATE_IT")}
          >
            <Text>Testit</Text>
          </TouchableOpacity>

我知道 useContext 有效。如果我在 App.js 中将“intitialState”设置为 true 并将其作为值提供给我的提供者,则子组件中的“access”属性会收到“true”,这会使组件更改其样式:

      <ActivateContext.Provider value={initialState}>
        <Navigation />
      </ActivateContext.Provider>

但是我没有设法使用 useContext 也将调度函数向下传递到组件树...

非常感谢任何帮助。

谢谢!

我认为您试图在 onClick 函数中错误地访问上下文值,此处:

onClick={() => ActivateContext.activeDispatch("ACTIVATE_IT")}

您正在将一个包含两个字段的对象传递给您的 value prop:

<ActivateContext.Provider  value={{activeStatus: state, activeDispatch: dispatch}}>
  <Navigation />
</ActivateContext.Provider>

所以您应该能够在您的页面中访问这两个值,执行如下操作:

const {activeStatus, activeDispatch} = useContext(ActivateContext);

并且,由于您的调度需要一个具有 type 字段的对象,因此您的 onClick 函数将类似于:

onClick={() => activeDispatch({type: "ACTIVATE_IT"})}