dispatch is not accessible from useContext

橙三吉。 提交于 2021-01-28 08:23:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!