useEffect实现componentWillUnmount⽣命周期函数(四)
在写React应⽤的时候,在组件中经常⽤到componentWillUnmount⽣命周期函数(组件将要被卸载时执⾏)。⽐如我们的定时器要清空,避免发⽣内存泄漏;⽐如登录状态要取消掉,避免下次进⼊信息出错。所以这个⽣命周期函数也是必不可少的,这节课就来⽤useEffect来实现这个⽣命周期函数,并讲解⼀下useEffect容易踩的坑。
useEffect解绑副作⽤
学习React Hooks时,我们要改掉⽣命周期函数的概念(⼈往往有先⼊为主的⽑病,所以很难改掉),因为Hooks叫它副作⽤,所
以componentWillUnmount也可以理解成解绑副作⽤。这⾥为了演⽰⽤useEffect来实现类似componentWillUnmount效果,先安装React-Router路由,进⼊项⽬根本录,使⽤npm进⾏安装。
npm install --save react-router-dom
然后打开Example.js⽂件,进⾏改写代码,先引⼊对应的React-Router组件
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
在⽂件中编写两个新组件,因为这两个组件都⾮常的简单,所以就不单独建⽴⼀个新的⽂件来写了。
function Index() {
return <h2>JSPang</h2>;
}
function List() {reacthooks理解
return <h2>List-Page</h2>;
}
有了这两个组件后,接下来可以编写路由配置,在以前的计数器代码中直接增加就可以了。
return (
<div>
<p>You clicked {count} times</p>
<button onClick={()=>{setCount(count+1)}}>click me</button>
<Router>
<ul>
<li> <Link to="/">⾸页</Link> </li>
<li><Link to="/list/">列表</Link> </li>
</ul>
<Route path="/" exact component={Index} />
<Route path="/list/" component={List} />
</Router>
</div>
)
然后到浏览器中查看⼀下,看看组件和路由是否可⽤。如果可⽤,我们现在可以调整useEffect了。在两个新组件中分别加⼊useEffect()函数: function Index() {
useEffect(()=>{
console.log('useEffect=>⽼弟,你来了!Index页⾯')
)
return <h2>JSPang</h2>;
}
function List() {
useEffect(()=>{
console.log('useEffect=>⽼弟,你来了!List页⾯')
})
return <h2>List-Page</h2>;
}
这时候我们点击Link进⼊任何⼀个组件,在浏览器中都会打印出对应的⼀段话。这时候可以⽤返回⼀个函数的形式进⾏解绑,代码如下:function Index() {
useEffect(()=>{
console.log('useEffect=>⽼弟你来了!Index页⾯')
return ()=>{
console.log('⽼弟,你⾛了!Index页⾯')
}
})
return <h2>JSPang</h2>;
}
这时候你在浏览器中预览,我们仿佛实现了componentWillUnmount⽅法。但这只是好像实现了,当点击计数器按钮时,你会发现⽼弟,你⾛
了!Index页⾯,也出现了。这到底是怎么回事那?其实每次状态发⽣变化,useEffect都进⾏了解绑。
useEffect的第⼆个参数
那到底要如何实现类似componentWillUnmount的效果那?这就需要请出useEffect的第⼆个参数,它是⼀个数组,数组中可以写⼊很多状态对应的变量,意思是当状态值发⽣变化时,我们才进⾏解绑。但是当传空数组[]时,就是当组件将被销毁时才进⾏解绑,这也就实现
了componentWillUnmount的⽣命周期函数。
function Index() {
useEffect(()=>{
console.log('useEffect=>⽼弟你来了!Index页⾯')
return ()=>{
console.log('⽼弟,你⾛了!Index页⾯')
}
},[])
return <h2>JSPang</h2>;
}
为了更加深⼊了解第⼆个参数的作⽤,把计数器的代码也加上useEffect和解绑⽅法,并加⼊第⼆个参数为空数组。代码如下:
function Example(){
const [ count , setCount ] = useState(0);
useEffect(()=>{
console.log(`useEffect=>You clicked ${count} times`)
return ()=>{
console.log('====================')
}
},[])
return (
<div>
<p>You clicked {count} times</p>
<button onClick={()=>{setCount(count+1)}}>click me</button>
<Router>
<ul>
<li> <Link to="/">⾸页</Link> </li>
<li><Link to="/list/">列表</Link> </li>
</ul>
<Route path="/" exact component={Index} />
<Route path="/list/" component={List} />
</Router>
</div>
)
}
这时候的代码是不能执⾏解绑副作⽤函数的。但是如果我们想每次count发⽣变化,我们都进⾏解绑,只需要在第⼆个参数的数组⾥加
⼊count变量就可以了。代码如下:
function Example(){
const [ count , setCount ] = useState(0);
useEffect(()=>{
console.log(`useEffect=>You clicked ${count} times`)
return ()=>{
console.log('====================')
}
},[count])
return (
<div>
<p>You clicked {count} times</p>
<button onClick={()=>{setCount(count+1)}}>click me</button>
<Router>
<ul>
<li> <Link to="/">⾸页</Link> </li>
<li><Link to="/list/">列表</Link> </li>
</ul>
<Route path="/" exact component={Index} />
<Route path="/list/" component={List} />
</Router>
</div>
)
}
这时候只要count状态发⽣变化,都会执⾏解绑副作⽤函数,浏览器的控制台也就打印出了⼀串=================。
转⾃:jspang/posts/2019/08/12/react-hooks.html