问题描述
import React,{ createContext,useReducer } from "react";
import Reducer from "./UserReducer";
const initialState = {
user: {},error: null
};
const Store = ({ children }) => {
const [state,dispatch] = useReducer(Reducer,initialState);
return (
<Context.Provider value={[state,dispatch]}>
{children}
</Context.Provider>
);
};
export const Context = createContext(initialState);
export default Store;
我已经用它包裹了我的应用程序
<Store>
<ThemeProvider theme={Theme}>
<CssBaseline />
<Navbar />
<Wrapper>
<Profile />
</Wrapper>
</ThemeProvider>{" "}
</Store>
还有其他设置,我的身份验证页面位于单独的包装器中,所以我也用商店包装了它。
import Store from "../../../context/Store";
export default function Wrapper({ children }) {
const classes = useStyles();
return (
<Store>
//different dumb containers opening
{children}
//different dumb containers closing
</Store>
);
}
现在当我尝试访问子组件中的上下文时
import React,{ useContext } from "react";
import { Context } from "../../../context/Store";
import { SET_USER } from "../../../context/UserTypes";
function SignUp(props) {
const [state,setState] = React.useState({ ...initialState });
const [userData,dispatch] = useContext(Context);
console.log(userData,dispatch,"check");
// rest of component
出现以下错误
TypeError: undefined is not a function
我试图在不解构它的情况下记录 useContext 的结果,但它只有全局状态,但没有调度功能。
Reactjs 版本 = 17.0.1
更新:dispatch 可以在 withAuthenticator HOC 外部访问,但不能在内部访问,因此可能是放大问题。
我在 amplify repo 上打开了问题。
Unable to access dispatch from useContext from components wrapped withAuthenticator
解决方法
我认为有些事情可能是潜在问题。
主要问题是您的 Context
的值。创建上下文时,其值是一个状态 (createContext(initialState)
)。但是,当您将 value
传递给 Context.Provider
时,您将给它一个包含状态和调度函数 (value={[state,dispatch]}
) 的数组。您需要对上下文中包含的值保持一致。是状态对象还是元组?
您描述的错误似乎是在 Context
之外访问 Provider
时会发生的情况。它会回退初始上下文值,它只是一个状态而不是一个 [state,dispatch]
元组。
您需要将初始值更改为与您期望的值相匹配的值。
const Context = createContext([
initialState,// state
() => console.error("Cannot dispatch because Context was used outside of a provider") // dispatch
]);
但您还需要弄清楚为什么 useContext
获取默认值而不是来自 Provider
的值。我不确定接下来的两个问题是否会解决这个问题。
看起来 Profile
组件位于两个不同的 Store
提供程序中。一种在一切之外,一种在 Wrapper
组件内部。这些将有两个单独的状态实例。当同一个上下文有两个提供者时,React 使用内部的一个。因此,您从 Profile
分派的任何操作都不会更新 Store
的外部版本。
您在 Context
组件中使用 Store
变量之后创建它。你应该换个顺序。