Получение бесконечного l oop при использовании React Context Dispatch в useEffect - PullRequest
0 голосов
/ 19 июня 2020

Я работаю над проектом и создал контекст, который должен хранить данные моих проектов. Я включил отправку контекста внутри useEffect в компонент, который должен передавать объект данных в контекст, но я столкнулся с проблемой, когда я являюсь бесконечным l oop. Я полностью упростил структуру и до сих пор не могу понять, в чем моя проблема. Я вставил код ниже. Кто-нибудь знает, что я мог делать не так?

// 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]);
    .
    .
    .

1 Ответ

1 голос
/ 19 июня 2020

Я думаю, это происходит потому, что useEffect вызывается во время первого рендеринга, он выполняет dispatch, который вызывает ваш редуктор, который возвращает новый объект { dataContextInitialState }.

Новый объект передается вашему компоненту, useEffect проверяет, является ли объект dataContext таким же, как в предыдущем рендере, но он отличается, потому что это новый объект, поэтому он повторно выполняет useEffect и у вас есть l oop.

Возможное решение

Насколько я понимаю, с этим фрагментом кода

const dataContextInitialState = { test: 1 };

case "update":
  return {
    dataContextInitialState,
  };

ваше состояние становится следующим:

{
  dataContextInitialState: {
    test: 1
  }
}

Я предполагаю, что вы хотели иметь состояние, которое представляет собой объект с ключевыми именами test, вы можете попробовать изменить свой код следующим образом:

case "update":
  return dataContextInitialState;

...