useEffect 是react 新版本推出的一个特别常用的 hooks 功能之一,useEffect 可以在组件渲染后实现各种不同的副作用,它使得函数式组件同样具备编写类似类组件生命周期函数的功能.
因为useEffect只在渲染后执行,所以useEffect只能替代render后的生命周期函数。即componentDidMount,componentDidUpdate 和 componentWillUnmount
只为useEffect传入回调函数一个参数时,回调函数会在每次组件重新渲染后执行,即对应于componentDidUpdate。
使用方法如下
useEffect(() => console.log('updated...'));
在使用这个方式的useEffect时,要特别注意在回调函数内部避免循环调用的问题,比如useEffect回调函数内部改变了state,state的更新又触发了useEffect。
为useEffect传入第二个参数,第二个参数是一个包含了state对象的数组,useEffect只会在数组内的一个或多个state发生变化并且重新渲染了组件后执行传入的回调函数
const [count, setCount] = useState(0);
useEffect(()=>{
console.log(count);
}, [count])
如上代码,只有在count的值发生更改时,回调函数才会执行,或者会跳过。用这个方法可以减少不必要的操作。
这个方式依托于上面的方式理解说简单也简单说不简单也不简单。
官方的解释是
如果你传入了一个空数组([]),effect 内部的 props 和 state 就会一直拥有其初始值。
这样理解就相对简单了,意思就是只会在组件初始化时执行一次,后面的state和props的改变都不会执行了。 这就会让我们很自然想到我们用得几乎最多的componentDidMount钩子函数了。代码如下
const [count, setCount] = useState(0);
useEffect(()=>{
console.log(count);
}, [])
这个使用方法是固定用法,就不做过多说明,示例也粘贴至官网示例,这里大概提一下:
结合上面的方法,如果在示例中传入和不传入第二个参数的区别
function FriendStatus(props) {
// ...
useEffect(() => {
// ...
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});