React Hook useReducer всегда работает дважды - PullRequest
1 голос
/ 07 апреля 2020

Я загружаю данные из API publi c после монтирования моего компонента. Когда данные загружаются, я передаю их в редуктор, но он всегда срабатывает дважды. Вот что у меня есть:

function MyComponent(props) {
   function reducer(data, action) {
      switch (action.type) {
         case 'INITIALIZE':
            return action.payload;
         case 'ADD_NEW':
            const newData = {...data};
            newData.info.push({});
            return newData;
      }
   }

   const [data, dispatch] = React.useReducer(reducer, null);

   useEffect(() => {
      fetch(URL)
        .then(response => {
            dispatch({
               type: 'INITIALIZE',
               payload: response
            });
         })
        .catch(error => {
            console.log(error);
         });
   }, []);

   const addNew = () => {
      dispatch({ type: 'ADD_NEW' });
   }

   return(
       <>data ? data.info.length : 'No Data Yet'</>
   );

}

Как видите, компонент ждет данных для заполнения редуктора, который, когда INITIALIZE также вызывается дважды, но мне было все равно, пока Мне нужно было вызвать ADD_NEW, потому что в этом случае он добавляет два пустых объекта в массив вместо одного. Я не был в документации для побочных эффектов, но я был не в состоянии решить это.

Как лучше всего с этим справиться?

1 Ответ

1 голос
/ 07 апреля 2020

Вот как бы я справился с этой проблемой. Основной причиной повторного запуска эффекта действия было то, что у вас был редуктор в функции компонента. Я также пошел дальше и исправил несколько других проблем.

Из-за того, как работает выборка, код выборки был немного не в порядке. Вы должны получить тип данных из ответа, который дает другое обещание вместо данных напрямую.

Вам также нужно было использовать рендеринг {}, чтобы указать, что вы используете javascript вместо текста.

import React, { useReducer, useState, useEffect } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";
const url = `https://picsum.photos/v2/list?page=3&limit=1`;
function App(props) {
  const [data, dispatch] = React.useReducer(reducer, null);

  useEffect(() => {
    fetch(url)
      .then(async response => {
        dispatch({
          type: "INITIALIZE",
          payload: (await response.json())
        });
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

  const addNew = () => {
    dispatch({ type: "ADD_NEW" });
  };
  console.log("here");
  return (
    <>
      <div>{data ? JSON.stringify(data) : "No Data Yet"}</div>
      <button onClick={addNew}>Test</button>
    </>
  );
}

render(<App />, document.getElementById("root"));
function reducer(data, action) {
  switch (action.type) {
    case "INITIALIZE":
      console.log(action.payload, "Initialize");
      return action.payload;
    case "ADD_NEW":
      const newData = { ...data };
      newData.info = newData.info || [];
      newData.info.push({});
      console.log(newData);
      return newData;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...