为什么在每个渲染器上都调用`useEffect`中的清理函数?

我一直在学习React,并且我读到从返回的函数useEffect是要进行清理的,而在组件卸载时,React会执行清理。

因此,我进行了一些试验,但在以下示例中发现,每次重新发布组件时都会调用该函数,而不是仅从DOM上卸载该组件时才调用该函数,即,每次重新发布组件时都会调用该函数console.log("unmount");

这是为什么?

function Something({ setShow }) {

const [array, setArray] = useState([]);

const myRef = useRef(null);

useEffect(() => {

const id = setInterval(() => {

setArray(array.concat("hello"));

}, 3000);

myRef.current = id;

return () => {

console.log("unmount");

clearInterval(myRef.current);

};

}, [array]);

const unmount = () => {

setShow(false);

};

return (

<div>

{array.map((item, index) => {

return (

<p key={index}>

{Array(index + 1)

.fill(item)

.join("")}

</p>

);

})}

<button onClick={() => unmount()}>close</button>

</div>

);

}

function App() {

const [show, setShow] = useState(true);

return show ? <Something setShow={setShow} /> : null;

}

实时示例:https://codesandbox.io/s/vigilant-

leavitt-z1jd2

回答:

卸载组件时,React执行清理。

我不确定您在哪里阅读此书,但此说法不正确。当对该钩子的依赖关系发生更改并且效果钩子需要使用新值再次运行时,React将执行清理。此行为是为了维持视图对更改数据的反应性。以官方示例为例,假设某个应用程序订阅了朋友个人资料中的状态更新。作为您的好朋友,您决定不与他们成为朋友,并与其他人成为朋友。现在,该应用程序需要退订前一个朋友的状态更新,并收听您新朋友的更新。这是自然的,并且可以通过useEffect工作方式轻松实现。

 useEffect(() => { 

chatAPI.subscribe(props.friend.id);

return () => chatAPI.unsubscribe(props.friend.id);

}, [ props.friend.id ])

通过在依赖项列表中包含好友ID,我们可以指示挂钩仅在好友ID更改时才需要运行。

在您的示例中,您已经array在依赖项列表中指定了,并且您将按设置的时间间隔更改数组。每次更改数组时,挂钩都会重新运行。

您只需从依赖项列表中删除该数组并使用该setState挂钩的回调版本就可以实现正确的功能。回调版本始终在状态的先前版本上运行,因此,每次数组更改时都无需刷新挂钩。

  useEffect(() => {

const id = setInterval(() => setArray(array => [ ...array, "hello" ]), 3000);

return () => {

console.log("unmount");

clearInterval(id);

};

}, []);

clearInterval当创建清除函数时,该值在(捕获)时关闭(捕获),因此将直接使用id 。无需将其保存到引用。

以上是 为什么在每个渲染器上都调用`useEffect`中的清理函数? 的全部内容, 来源链接: utcz.com/qa/433987.html

回到顶部