useEffect 缺少依赖项,但是当我添加它时,我收到'maximum update depth exceeded'错误



我试图用钩子来绕开我的头,但我遇到了一个重复的问题。 在下面链接的示例中,我有一个对数组进行排序的 useEffect 钩子。 排序顺序由状态值确定,我有一个按钮可以切换该状态值。

一切都按照我想要的方式工作,当组件安装时对数组进行排序,然后单击按钮。

但是,我从 linter 收到一个错误,即需要在 useEffect 钩子中将值数组声明为依赖项。 如果我这样做,我会收到"超出最大更新深度"错误。 我不确定该怎么做,我将不胜感激任何帮助!

链接到代码

谢谢你看一看,这对我来说真的意义重大!

我没有看到你的代码有任何问题。我要做的只是简单地忽略警告,添加// eslint-disable-next-line react-hooks/exhaustive-deps如下所示:

useEffect(() => {
function sortValues() {
let sorted;
const array = [...values];
if (ascValue) {
sorted = array.sort((a, b) => a - b);
} else {
sorted = array.sort((a, b) => b - a);
}
setValues(sorted);
}
sortValues();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ascValue]);

也许sortValues()上的一个缩短:

function sortValues() {
const compare = ascValue ? (a, b) => a - b : (a, b) => b - a;
setValues([...values].sort(compare));
}

我希望这有所帮助!

理想情况下,您可以添加一些条件/检查以查看values是否已经具有所需的值。由于每次渲染时似乎都会调用setValues触发重新渲染,乘以无穷大。

潜在地,使用像 Lodash 的 isEqual 与 Lodash 的 orderBy 相结合可以做到这一点(因为排序会改变原始数组(。

const [ascValue, setAscValue] = useState(true);
const [values, setValues] = useState([
{ id: 10 },
{ id: 5 },
{ id: 12 },
{ id: 1 },
{ id: 2 },
{ id: 900 },
{ id: 602 }
]);
useEffect(() => {
function sortValues() {
const sorter = ascValue ? "asc" : "desc";
if (!_.isEqual(values, _.orderBy(values, ["id"], [sorter]))) {
console.log("logged");
setValues(() => _.orderBy(values, ["id"], [sorter]));
}
}
sortValues();
}, [ascValue, values]);

关键是,默认情况下,useEffect 不应该在每个渲染上设置状态(它可以在渲染完成并且用户触发操作后

设置状态(。CodeSandbox 的一个分支,用于演示副作用仅在满足条件时才应更新组件状态。

这并不奇怪 - 当您在依赖项数组中添加值列表时,useEffect 将在值列表的每次更改时执行 - 这会导致无限循环:)

根据前面的回答@norbitrial,隐藏错误并不能解决问题,因为范围中的每个依赖项都必须在依赖项数组中声明,避免它可能会导致意外行为。

我建议在这种情况下考虑使用useReducer。这将导致依赖数组的修改逻辑可以移出useEffect钩子的范围 - 并且您不会被迫将其作为useEffect的依赖项附加。

相关内容

  • 没有找到相关文章

最新更新