发布于 2026-01-06 12 阅读
0

重大使用效果错误

重大使用效果错误

这篇文章最初发表在我的个人博客上。

在 Reactjs 中,我们经常会遇到无限循环或无谓的重新渲染。这几乎无法避免,但我们可以更加注意。导致这类问题的原因之一是 useEffect;接下来,我将讨论使用 useEffect 时可能犯的一个错误,并讲解如何避免它。

错误😮

看看这个:

const [state, setState] = React.useState(0);
React.useEffect(() => {
  console.log("re-rendering");
}, [{ ...someData }])
Enter fullscreen mode Exit fullscreen mode

如果我们setState多次执行此操作,则会在控制台中看到以下内容:

re-rendering
re-rendering
re-rendering
Enter fullscreen mode Exit fullscreen mode

等等,什么?我们明明只是传递了someData一个依赖列表,为什么会记录这个?这跟……根本没关系state。是的,确实没关系,但请更仔细地查看依赖列表;我们传递的是一个内联对象,这意味着它每次都与之前的版本不同;每次组件重新渲染时,我们都会创建一个新的对象。请看这里:

{ ...someData } === { ...someData } // false
{} === {} // false
[] === [] // false
// all are inline and have different references
Enter fullscreen mode Exit fullscreen mode

useEffect它会缓存依赖项列表,并检查它是否等于下一个值。这就是为什么在这个工具看来,内联的非原始值(例如[],` {}&&`、`&& {...data}`、`&&`……)总是不同的原因。

Symbol()这里是个例外,每次创建它时都会有所不同,但它是一个原始值。

例如,你看,我看到很多开发者像这样检查数组的一部分:

const [state, setState] = React.useState([1, 2, 3, 4, 5]);
React.useEffect(() => {
  console.log("re-rendering");
}, [state.slice(0, 2)]); 
/* 
    prevVal = state.slice(0, 2) // first render
        ***
    nextVal = state.slice(0, 2) // second render
        ***
    prevVal === nextVal // false
*/
Enter fullscreen mode Exit fullscreen mode

预期行为是检查 1 到 3 个值,但这样做行不通,因为该slice方法总是返回一个新的数组(引用)。

希望您喜欢这篇文章。别忘了分享并留言。如果您想告诉我什么,可以在Twitter上留言或在其他任何地方提及我。您还可以订阅我的电子报并在GitHub上关注我。👋🏻

文章来源:https://dev.to/aslemammad/big-useeffect-mistake-7jm