Home > Blockchain >  useContext does not forward dispatch function from useReducer
useContext does not forward dispatch function from useReducer

Time:04-29

I am trying not to use Redux. So I am stuck with useContext in combination with useReducer for globaal state management. My problem: I can not update the state from a child component using dispatch.

Let me explain in more detail. My context file is pretty straight forward:

import React, { createContext } from "react";

const ActivateContext = createContext();

export default ActivateContext;

I import it in App.js and wrap it around the root component within my navigation:

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>
  );

I then import "ActivateContext" in my child component called "Child". I save everything in the constant "activated". I then use "activated" in the prop called "access":

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

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

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

I tried to add a button to the component "Child" to change the state in App.js but nothing happens:

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

I know useContext works. If I i set "intitialState" to true in App.js and give it as a value to my provider, the "access" prop in the Child component receives "true", which makes the component change its style:

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

However I do not manage to use useContext to also pass down the dispatch function down the component tree...

Any help is much appreciated.

Thanks!

CodePudding user response:

I think you're trying to access your context values incorrectly in your onClick function, here:

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

You're passing an object with two fields to your value prop:

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

So you should be able to access both of these values, in your pages, doing something like:

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

And, since your dispatch expects an object with a type field, your onClick function would be something like:

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