gpt4 book ai didi

javascript - 使用 useEffect 和 useCallback 无限循环 - Reactjs

转载 作者:行者123 更新时间:2023-12-02 18:12:13 25 4
gpt4 key购买 nike

不知怎么的,我遇到了一个无限循环,我确实解决了这个奇怪的情况,但我收到了一个警告,我希望修复这个警告。

这是有效的代码:

import { ArrowDropDown, ArrowRight } from "@material-ui/icons";
import React, { useState, useEffect, useCallback } from "react";
import "./tree.css";

const Tree = ({ explorer }) => {
const [expand, setExpand] = useState(true);
const [arrow, setArrow] = useState(false);

const stateHandler = () => {
setExpand(!expand);
setArrow(!arrow);
};

useEffect(() => {
//this function will display only the first Tree as init the page.
stateHandler();
}, []);

return (
<div>
<div className="treeInfo">
{arrow ? (
<ArrowDropDown className="treeIcon" />
) : (
<ArrowRight className="treeIcon" />
)}

<span className="treeTitle" onClick={stateHandler}>
{explorer.name}
</span>
</div>

<div
style={{
display: expand ? "block" : "none",
paddingLeft: 20,
cursor: "pointer",
}}
>
{explorer.items.map((explore) => {
return <Tree key={explore.id} explorer={explore} />;
})}
{/* {explorer.items.map((explore) => (
<Tree explorer={explore} />
))} */}
</div>
</div>
);
};

export default Tree;

这是警告:

src\components\Tree\Tree.js
Line 17:6: React Hook useEffect has a missing dependency: 'stateHandler'. Either include it or remove the dependency array react-hooks/exhaustive-deps

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

WARNING in src\components\Tree\Tree.js
Line 17:6: React Hook useEffect has a missing dependency: 'stateHandler'. Either include it or remove the dependency array react-hooks/exhaustive-deps

webpack compiled with 1 warning

**

  • 结果 : (这很好,我想显示一个 TreeView 文件)

**

result

据我所知,我收到此警告是因为 useEffect 没有依赖项,当我添加 stateHandler 依赖项时,我得到了一个无限循环,所以我添加了一个回调函数,但它仍然没有解决无限循环。这是带有 useCallback 的代码(它是相同的代码,只是带有 useCallback 和一些 useEffect 的配置):

 const initTree = useCallback(() => {
setExpand(!expand);
setArrow(!arrow);
}, [setExpand, setArrow, arrow, expand]);

useEffect(() => {
//this function will display only the first Tree as init the page.
initTree();
}, [initTree]);

最佳答案

你需要改变这个:

 const initTree = useCallback(() => {
setExpand(!expand);
setArrow(!arrow);
}, [setExpand, setArrow, arrow, expand]);

为此:

 const initTree = useCallback(() => {
setExpand(e => !e);
setArrow(a => !a);
}, []);

否则会发生这样的事情:

  1. 组件渲染,initTree 变量用函数初始化,Effect 运行,setExpandsetArrow 被调用。
  2. 触发新的渲染
  3. useCallback Hook 检查 initTree 的 deps 是否已更改,是的,arrowexpand 已更改事实上,因此 initTree 变量被更新为一个新函数
  4. 效果会检查 initTree 是否与之前的渲染发生了变化,是的,它已经发生变化,因此效果会再次调用 initTree 执行。
  5. 您陷入了无限渲染循环。

如果您不将 setState 放在 deps 中,Eslint 不应该提示缺少 deps,因为它们在渲染期间不会改变,除非您通过 props 传递它们。

关于javascript - 使用 useEffect 和 useCallback 无限循环 - Reactjs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72147191/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com