1

I'm working on a project and created a context that is supposed to store my projects data. I included the context dispatch inside of a useEffect in a component which is supposed to pass the data object to the context but I am running into an issue where I am an infinite loop. I completely simplified the structure and I still can't figure out what my problem is. I pasted the code below. Does anyone know what I could be doing wrong?

// DataContext.js
import React, { useReducer } from "react";

export const DataContext = React.createContext();

const dataContextInitialState = { test: 1 };

const dataContextReducer = (state, action) => {
  switch (action.type) {
    case "update":
      console.log(state);
      return {
        ...state,
        action.value,
      };

    default:
      return dataContextInitialState;
  }
};

export const DataContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(
    dataContextReducer,
    dataContextInitialState
  );

  return (
    <DataContext.Provider
      value={{
        state,
        dispatch,
      }}
    >
      {children}
    </DataContext.Provider>
  );
};

// Component that is accessing context

    .
    .
    .
  useEffect(() => {
    dataContext.dispatch({
      type: "update",
    });
  }, [dataContext]);
    .
    .
    .
2
  • Remove dependency from useEffect. The second param in useReducer initializes state... Commented Jun 18, 2020 at 22:59
  • When I remove the dependency I get an error: React Hook useEffect has a missing dependency: 'dataContext' Commented Jun 18, 2020 at 23:26

1 Answer 1

1

I think this happens because the useEffect gets called during the first render, it executes dispatch that calls your reducer which returns a new object { dataContextInitialState }.

The new obect is passed down to your component, useEffect checks if the dataContext object is the same as in the previous render, but it is different because it's a new object so it re-executes the useEffect and you have the loop.

A possible solution

From my understanding with this piece of code

const dataContextInitialState = { test: 1 };

case "update":
  return {
    dataContextInitialState,
  };

your state becomes this:

{
  dataContextInitialState: {
    test: 1
  }
}

I guess that what you wanted was to have a state which is an object with a key names test, you can try modifying your code like this:

case "update":
  return dataContextInitialState;

Sign up to request clarification or add additional context in comments.

1 Comment

I actually left my code as ``` case "update": console.log(state); return { dataContextInitialState, }; ``` as an example. What I really want is something along the lines of ``` case "update": console.log(state); return { ...state, action.value, }; ``` (I guess I can't style as a comment? I updated the original post to make it more clear)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.