useEffect可以用作componentWillUnmount(),需要写在回调函数里,并返回,比如取消计时器如下:
const [count, setCount] = React.useState(0)//返回一个数组,第一个是状态state
function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById('root'))
}
React.useEffect(() => {
console.log('@@@--');
let timer = setInterval(() => {
setCount(count=>count + 1)
}, 1000)
return () => {
console.log('结束');//为什么监控count后每次更新count的时候也会运行这句,但是下面的不会运行
clearInterval(timer)
}
}, [count])//空数组相对于组件挂载时didmount,只对状态进行监控
确实可以取消计时器,但是我发现console.log(‘结束’)这句不是只有在我点击卸载组件的时候才运行,而是每一次计时器更新count,就会输出一次“结束”
我发现这return的两行代码居然会分别运行,更新count只运行console.log(‘结束’),在unmountComponentAtNode的时候就俩都运行,为了验证我只是计时器原因,我人为取消计时器,点击更新count,发现在return中唯一的一句console.log(‘结束’)也输出了,这根本就不是在willunmount的时候才运行的逻辑,
React.useEffect(() => {
console.log('@@@--');
//let timer = setInterval(() => {
// setCount(count=>count + 1)
//}, 1000)
return () => {
console.log('结束');//为什么监控count后每次更新count的时候也会运行这句,但是下面的不会运行
// clearInterval(timer)
}
}, [count])//空数组相对于组件挂载时didmount,只对状态进行监控
然后我发现跟教学视频中的一个差别是,在监控的数组那里,视频里面是空数组,意思就是都不监控。而我写了count,意思是对count进行监控,
然后我改成空数组后,对上诉两种情况都进行了试验,发现return充当willunmount的作用就实现了
React.useEffect(() => {
console.log('@@@--');
let timer = setInterval(() => {
setCount(count=>count + 1)
}, 1000)
return () => {
console.log('结束');//为什么监控count后每次更新count的时候也会运行这句,但是下面的不会运行
clearInterval(timer)
}
}, [])//空数组相对于组件挂载时didmount,只对状态进行监控
所以是不是只要在数组里面写了,不再是不监控状态的时候,return作为willunmount的作用才能实现,不然就不行呢,后来查资料得知,useEffect中的回调函数不只是在组件销毁前调用,下一次render前也会调用
,下面是别人文章的引用
这里的重构用到两个hook:useState,useEffect。useState相信大家都了解了(不了解的戳这里:hooks官方文档),这里我说一说useEffect的用法:首先它对标的是class中的各个生命周期,接收的第一个参数是一个回调函数effectCallback,这个回调是这样的形式:() => (void | (() => void | undefined)),如果useEffect没有第二个参数,effectCallback会在每次render(或者组件函数被调用)后被调用,相当于componentDidMount+componentDidupdate,值得注意的是effectCallback往往还会return一个函数,它的角色类似componentWillUnmount,会在下一次render前或销毁组件前运行。那么这里我只需要’像componentDidMount那样在组件第一次render后运行一次而不是每次render后都运行’要如何实现呢?这就需要传给useEffect第二个参数-一个数组了,它的角色有点类似于componentShouldUpdate,一般来说它由state和props中的数据构成,每次render,useEffect会判断这个数组与上一次render是否完全一致,如果完全一致effectCallback就不会进入事件队列并运行了,想要实现componentDidmount的效果只需传一个空数组,这样数组每次都完全一致了。
引自:https://blog.csdn.net/weixin_33832340/article/details/91383424
视频笔记
(1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
(2). React中的副作用操作:
发ajax请求数据获取
设置订阅 / 启动定时器
手动更改真实DOM
(3). 语法和说明:
useEffect(() => {
// 在此可以执行任何带副作用操作
return () => { // 在组件卸载前执行
// 在此做一些收尾工作, 比如清除定时器/取消订阅等
}
}, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行
(4). 可以把 useEffect Hook 看做如下三个函数的组合
componentDidMount()
componentDidUpdate()
componentWillUnmount()