问题
i have simple store
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;
i have wrapped my app with it like
<Store>
<ThemeProvider theme={Theme}>
<CssBaseline />
<Navbar />
<Wrapper>
<Profile />
</Wrapper>
</ThemeProvider>{" "}
</Store>
There is additional setup as well where my authentication pages are located in separate wrapper so i wrapped that with store as well.
here is code for that wrapper (extra removed).
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>
);
}
Now when i try to access context within child component like
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
i get following error
TypeError: undefined is not a function
i tried to log result of useContext without destructuring it but all it had was global state but no dispatch function with it.
Reactjs version = 17.0.1
Update: dispatch is accessible outside withAuthenticator HOC but not within that so it might be amplify issue.
i have opened issue on amplify repo.
Unable to access dispatch from useContext from components wrapped withAuthenticator
回答1:
There a few things I see that could be potential issues.
The major problem is the value of your Context
. When you create the context, its value is a state (createContext(initialState)
). But when you pass a value
to the Context.Provider
you are giving it an array which contains both a state and a dispatch function (value={[state, dispatch]}
). You need to be consistent about the value that is contained in the context. Is it a state object or a tuple?
The error that you are describing seems like what would happen if the Context
is accessed outside of a Provider
. It would fall back the initial context value which is just a state rather than a [state, dispatch]
tuple.
You need to change the initial value to something that matches the value that you are expecting.
const Context = createContext([
initialState, // state
() => console.error("Cannot dispatch because Context was used outside of a provider") // dispatch
]);
But you also need to figure out why the useContext
is getting the default value instead of one from a Provider
. I'm not sure if these next two issues will fix that or not.
It looks like the Profile
component is inside of two different Store
providers. One which is outside of everything and one which is inside of the Wrapper
component. These will have two separate instances of state. When there are two providers for the same context React uses the inner one. So any actions that you dispatch from Profile
won't update the outer version of Store
.
You create the Context
variable after you use it in your Store
component. You should switch the order.
来源:https://stackoverflow.com/questions/65511231/dispatch-is-not-accessible-from-usecontext