React Hook useReducer始终运行两次 [英] React Hook useReducer always running twice

查看:249
本文介绍了React Hook useReducer始终运行两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

安装组件后,我正在从公共API加载数据.加载数据后,我将其传递给reducer,但它始终会触发两次.这就是我所拥有的:

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

}

如您所见,该组件正在等待数据填充化简器,当INITIALIZE也被两次调用时,但是直到需要调用ADD_NEW时我才关心它,因为在这种情况下它将两个空白对象添加到数组中,而不仅仅是一个.我没有介绍副作用的文档,但是无法解决它.

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?

推荐答案

以下是我处理该问题的方法. 它重新运行动作效果的主要原因是因为您在组件的功能中使用了reducer.我还继续解决了其他几个问题.

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.

您还需要使用{}进行渲染,以表明您使用的是JavaScript而不是文本.

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

这篇关于React Hook useReducer始终运行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆