Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
454 views
in Technique[技术] by (71.8m points)

reactjs - dispatch is not accessible from useContext

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...