我正在尝试开发一个 React 应用程序,该应用程序使用 Hooks 显示项目列表,但正在发生无限循环。我认为该状态未被识别为已更新,但我无法说出原因。
我在文档中看到,我应该在 useEffect 函数上添加依赖项,但是当我删除对 useEffect 的依赖项时,它解决了问题。此外,这不是文档建议这样做,他们建议将所有依赖项放在列表中。
代码和框在这里:https://codesandbox.io/s/react-listing-forked-6sd99 如果我取消注释 Dashboard.ts
第 30 行,则可以看到无限循环,这是调用 dispatch
函数的行(并且codesandbox也会卡住几秒钟)。
useSelector 和 useEffect 函数如下,位于 Dashboard.tsx
文件中:
const catalog = useSelector<RootState, MetricState>(
(state) => state.fetchMetrics
);
console.log(catalog);
const dispatch = useDispatch();
const classes = useStyles();
useEffect(() => {
// dispatch(appReducer.actionCreators.fetchMetrics());
},[catalog, dispatch]));
模拟数据如下,位于apiCreators.js
文件中
export function fetchMetrics() {
const action = {
type: ACTION_TYPES.FETCH_METRICS,
payload: []
};
return fetchMetricsCall(action);
const fetchMetricsCall = (action) => async (dispatch) => {
try {
dispatch({
type: action.type,
payload: {
metrics: [
{
name: "one",
owner: {
team: "test"
}
},
{
name: "one",
owner: {
team: "test"
}
}
] //contains the data to be passed to reducer
}.metrics
});
} catch (e) {
dispatch({
type: ACTION_TYPES.FAILURE,
payload: console.log(e) //TODO: fix return type
});
}
};
最佳答案
主要问题是在此处找到的[catalog,dispatch]
内的catalog
:
useEffect(() => {
// dispatch(appReducer.actionCreators.fetchMetrics());
},[catalog, dispatch]));
问题在于 dispatch(appReducer.actionCreators.fetchMetrics())
导致 state.fetchMetrics(又名目录)
更新(这是一个对象),并且在比较对象/数组时,javascript 是“奇怪的”。
让我们看看这个:
let x = {a: 0}
let y = {a: 0}
let z = x
console.log(x === y) // this is FALSE
console.log(x === x) // this is TRUE
console.log(z === x) // this is TRUE
这篇文章更好地探讨了这个问题:http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html
每当状态发生变化时,useEffect
就会执行类似 if(oldState.catalog !== newState.catalog) {...rerender component}
的操作(我觉得这样可能真的不准确,但我希望它有助于说明正在发生的事情)。因此,组件重新渲染并对 dispatch
进行新的调用,这会更新状态,并且由于 useEffect
内的依赖项之一是一个对象,因此不可能进行更新告诉 useEffect
“停止重新渲染”。
有多种方法可以解决此问题,但您不应该需要 [catalog,dispatch]
内的 catalog
。只需删除它似乎就可以解决问题?
关于reactjs - 具有调度函数的 useSelector 和 UseEffect 由于不更新状态而创建循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67165650/