问题描述
安装组件后,我正在从公共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始终运行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!