什么是useEffect?
接收一个包含命令式、且可能有副作用代码的函数。 在函数组件主体内(这里指在 React 渲染阶段)改变 DOM、添加订阅、设置定时器、记录日志以及执行其他包含副作用的操作都是不被允许的,因为这可能会产生莫名其妙的 bug 并破坏 UI 的一致性。 使用 useEffect 完成副作用操作。赋值给 useEffect 的函数会在组件渲染到屏幕之后执行。
通过使用这个 Hook,你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。
为什么在组件内部调用 useEffect?
将 useEffect 放在组件内部让我们可以在 effect 中直接访问 count state 变量(或其他 props)。我们不需要特殊的 API 来读取它 —— 它已经保存在函数作用域中。Hook 使用了 JavaScript 的闭包机制,而不用在 JavaScript 已经提供了解决方案的情况下,还引入特定的 React API。
useEffect 会在每次渲染后都执行吗?
是的,默认情况下,它在第一次渲染之后和每次更新之后都会执行。(我们稍后会谈到如何控制它。)你可能会更容易接受 effect 发生在“渲染之后”这种概念,不用再去考虑“挂载”还是“更新”。React 保证了每次运行 effect 的同时,DOM 都已经更新完毕 如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
实现componentDidMount 的功能
useEffect的第二个参数为一个空数组,初始化调用一次之后不再执行,相当于componentDidMount。
function DidMount(){
useEffect(()=>{
console.log('挂载后只执行一次')
},[])
return (
<div>
hello word
</div>
)
}
实现组合 componentDidMount componentDidUpdate 的功能
当useEffect没有第二个参数时,组件的初始化和更新都会执行。
import React,{useState, useEffect} from 'react';
function Example(){
const [count, setCount] = useState(0);
useEffect(()=> {
console.log('没有第二个参数,组件初始化和更新都会执行')
})
}
实现组合 componentDidMount componentWillUnmount 的功能
useEffect返回一个函数,这个函数会在组件卸载时执行
function Example(){
const [count, setCount] = useState();
useEffect(()=> {
const id= setInterval(()=> {
setCount(c=>c+1)
}, 1000)
return ()=> clearInterval(id)
},[])
return (
<div>
hello word
</div>
)
}