Как обновить состояния useReducer в React? - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь получить элемент из localStorage и передать его тоже состояние useReducer.

Когда я переключаюсь с одной кнопки на другую, состояние кнопки не обновляется. Мой initialState обновился, но states не обновляет

my initialStates и states в console.log оба значения различаются. states всегда сохраняет предыдущие значения выбранной кнопки Genid значение элемента, а initialStates сохраняет текущие выбранные значения выбранной кнопки Genid значение элемента, но основная проблема заключается в том, что не было обновлено до части состояний useReducer

const Played = ( {Genid} ) => {
    console.log("Played page ")
    console.log("*************************************************")
    console.log(Genid)
    console.log(JSON.parse(localStorage.getItem(Genid)))

    const initialState = {
        DATA: JSON.parse(localStorage.getItem(Genid)) || [],
        isFetching:  localStorage.getItem(Genid) ? true : false,
        hasError: false,
    }
    console.log(initialState);


    const [states, dispatch] = useReducer(reducer, initialState)
    console.log(states)

1 Ответ

1 голос
/ 08 мая 2020

Итак, проблема в вашем коде была простой, initialState не был заполнен в reducer, потому что displayid изначально был undefined, а затем был установлен на ditto

Причина такого поведения заключается в том, что в Veritcal компонент, вы setDisplayId, и этот эффект запускается при начальной визуализации, и к тому времени undefined displayId уже используется компонентом Horizontal

Теперь с вашим кодом были и другие проблемы. Вы обновляли sessionStorage с помощью response.data.payload, но не было ключа payload в response.data

Также Movement компонент отображается на state.data, но это объект. Вместо этого вам нужно сопоставить state.data.abilities

Измененные фрагменты кода ниже

Движение. js

const Movement = ({ states }) => {
  console.log(states);
  return (
    <div>
      {states.data &&
        states.data.abilities.map(ability => <div>{ability.ability.name}</div>)}
    </div>
  );
};

export default Movement;

По горизонтали. js

  console.log(displayid);
  const initialState = {
    // data: displayid? JSON.parse(sessionStorage.getItem(displayid)): [],
    // isFetching: displayid && sessionStorage.getItem(displayid) ? true : false,
    // hasError: false
  };

  const [states, dispatch] = useReducer(reducer, initialState);
  // console.log(states);
  useEffect(() => {
    if (displayid && !sessionStorage.getItem(displayid)) {
      console.log(displayid);
      axios
        .get(`https://pokeapi.co/api/v2/pokemon/${displayid}/`)
        .then(response => {
          console.log(response);
          console.log(response.data);
          dispatch({
            type: "First",
            payload: response.data
          });
          console.log(response.data);
          sessionStorage.setItem(displayid, JSON.stringify(response.data));
        })
        .catch(error => {
          console.log(error);
          dispatch({
            type: "Second"
          });
        });
    } else if (displayid && sessionStorage.getItem(displayid)) {
      // populate data from localStorage
      const localData = {
        data: JSON.parse(sessionStorage.getItem(displayid)) || [],
        isFetching: sessionStorage.getItem(displayid) ? true : false,
        hasError: false
      };
      dispatch({ type: "POPULATE", payload: localData });
    }
  }, [displayid]);

Рабочая демонстрация

...