React Hook useReducer always running twice

≡放荡痞女 提交于 2020-05-15 05:56:07

问题


I am loading data from a public API after my component is mounted. When the data is loaded I am passing it to the reducer, but it always fires twice. This is what I have:

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

}

As you can see the component awaits for the data to populate the reducer, which, when INITIALIZE is also called twice, but I didn't care about it until I needed to call ADD_NEW, because in that case it adds two blank objects into the array instead of only one. I wen't into the documentation for side effects, but I was unable to solve it.

What is the best way to deal with this?


回答1:


Here's how I would deal with the issue. The main reason why it was re-running the action effect was because you had the reducer in the component's function. I also went ahead and fixed several other issues.

The fetch code was a little off due to how fetch works. You have to get the data type off of the response which gives another promise instead of the data directly.

You also needed to make the rendering use {} to indicate that you were using javascript rather than text.

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


来源:https://stackoverflow.com/questions/61071171/react-hook-usereducer-always-running-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!