[英]I have read the React Docs on Hooks and I'm confused. When is the useEffect Hook clean up function called?
The react docs explanation on when the useEffect clean up function is called is confusing and generic to be honest. 关于何时调用useEffect清理函数的react docs解释令人困惑且泛泛地说。 They even confuse you more by comparing the class mental model with hooks. 他们甚至通过将类思维模型与钩子进行比较来使您更加困惑。 Class based components work differently from function based components with hooks. 基于类的组件的工作方式不同于带有钩子的基于函数的组件。 React remembers the effect function you provided to useEffect, and runs it after flushing changes to the DOM which is understandable. React会记住您提供给useEffect的effect函数,并在将更改刷新到可以理解的DOM后运行它。 Now how and when is the function which is returned ("clean up function") called? 现在如何以及何时调用返回的函数(“清理函数”)?
Code example below: 下面的代码示例:
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
The function returned from the function given as first argument to useEffect
will be called when any element in the array given as second argument changes, or on every render if no second argument is given, or when the component is unmounted. 当作为第二参数给出的数组中的任何元素发生更改时,或者在每次渲染时(如果未提供第二参数),或者卸载组件时,将调用从作为useEffect
第一个参数给出的函数返回的函数。
Example 例
const { useEffect, useState } = React; function MyComponent({ prop }) { useEffect(() => { console.log('Effect!'); return () => console.log('Cleanup!') }, [prop]) return ( <div>{prop}</div> ); } function App() { const [value, setValue] = useState(0); useEffect(() => { setInterval(() => { setValue(value => value + 1); }, 1000) }, []) return value < 3 ? <MyComponent prop={value} /> : null; } ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>
Without using the second parameter it will get called on every render. 如果不使用第二个参数,它将在每个渲染器上调用。
This is often overkill, so it often a good idea to use the second parameter even if it's empty []
.. 这通常是多余的,因此即使第二个参数为空[]
也是一个好主意。
eg. 例如。
useEffect(() => {....}, []);
Doing the above will only then call the cleanup when the component is physically detached from the DOM. 当组件与DOM物理分离时,执行上述操作只会调用清除。
You can also pass props
instead of []
, this is handy if say a prop change, like what chat room you was in, it would then cleanup the current chat room, and initialize the new chat room etc. 您也可以传递props
而不是[]
,如果说更改props
,这很方便,例如您所在的聊天室,它将清理当前的聊天室,并初始化新的聊天室等。
So in your example passing [props.friend.id]
would make sense, because if the id changed, it would make sense to call the cleanup, and then run the effect again for the new id. 因此,在您的示例中,传递[props.friend.id]
是有意义的,因为如果id发生更改,则有必要调用清除操作,然后为新的id重新运行效果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.