P04:useEffect 实现 componentWillUnmount 生命周期函数
Posted wgchen~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P04:useEffect 实现 componentWillUnmount 生命周期函数相关的知识,希望对你有一定的参考价值。
阐述
在写React应用的时候,在组件中经常用到 componentWillUnmount
生命周期函数(组件将要被卸载时执行)。比如我们的定时器要清空,避免发生内存泄漏;比如登录状态要取消掉,避免下次进入信息出错。
所以这个生命周期函数也是必不可少的,本文就用 useEffect
来实现这个生命周期函数,并讲解一下 useEffect
容易踩的坑。
useEffect 解绑副作用
学习React Hooks 时,我们要改掉生命周期函数的概念,因为Hooks叫它副作用,所以componentWillUnmount
也可以理解成解绑副作用。
这里为了演示用useEffect
来实现类似componentWillUnmount
效果,先安装React-Router路由,进入项目根本录,使用npm进行安装。
npm install --save react-router-dom@5.2.0
然后打开 Example.js
文件,进行改写代码,先引入对应的React-Router组件。
import BrowserRouter as Router, Route, Link from "react-router-dom"
在文件中编写两个新组件,因为这两个组件都非常的简单,所以就不单独建立一个新的文件来写了。
function Index()
return <h2>willem</h2>;
function List()
return <h2>List-Page</h2>;
有了这两个组件后,接下来可以编写路由配置,在以前的计数器代码中直接增加就可以了。
function Example()
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked count times</p>
<button onClick=()=>setCount(count + 1)>Chlick 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>willem</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>willem</h2>;
这时候你在浏览器中预览,我们仿佛实现了 componentWillUnmount
方法。
但这只是好像实现了,当点击计数器按钮时,你会发现你走了Index页面,也出现了。
这到底是怎么回事那?
其实每次状态发生变化,useEffect都进行了解绑。
ReactHooksDemo\\demo01\\src\\Example.js
import React, useState, useEffect from 'react';
import BrowserRouter as Router, Route, Link from "react-router-dom"
function Index()
useEffect(()=>
console.log('useEffect=>我是Index页面')
return ()=>
console.log('你走了 Index页面')
,[])
return <h2>willem</h2>;
function List()
useEffect(()=>
console.log('useEffect=>我是 List页面')
)
return <h2>List-Page</h2>;
function Example()
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked count times</p>
<button onClick=()=>setCount(count + 1)>Chlick 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>
);
export default Example;
useEffect的第二个参数
那到底要如何实现类似 componentWillUnmount
的效果那?
这就需要请出useEffect的第二个参数,它是一个数组,数组中可以写入很多状态对应的变量,意思是当状态值发生变化时,我们才进行解绑。
但是当传空数组 []
时,就是当组件将被销毁时才进行解绑,这也就实现了componentWillUnmount
的生命周期函数。
function Index()
useEffect(()=>
console.log('useEffect=>我是Index页面')
return ()=>
console.log('你走了 Index页面')
,[])
return <h2>willem</h2>;
为了更加深入了解第二个参数的作用,把计数器的代码也加上 useEffect
和解绑方法,并加入第二个参数为空数组。
代码如下:
ReactHooksDemo\\demo01\\src\\Example.js
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)>Chlick 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)>Chlick 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状态发生变化,都会执行解绑副作用函数,浏览器的控制台也就打印出了一串=================
。
总结
通过对本文的学习,让我们对useEffect函数有了一个比较深入的了解,并且可以通过useEffect实现生命周期函数了,现在用React Hooks这种函数的方法编写组件,对比以前用Class编写组件几乎一样了。
ReactHooksDemo\\demo01\\src\\index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Example from './Example';
ReactDOM.render(<Example />, document.getElementById('root'));
ReactHooksDemo\\demo01\\src\\Example.js
import React, useState, useEffect from 'react';
import BrowserRouter as Router, Route, Link from "react-router-dom"
function Index()
useEffect(()=>
console.log('useEffect=>我是Index页面')
return ()=>
console.log('你走了 Index页面')
,[])
return <h2>willem</h2>;
function List()
useEffect(()=>
console.log('useEffect=>我是 List页面')
)
return <h2>List-Page</h2>;
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)>Chlick 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>
);
export default Example;
以上是关于P04:useEffect 实现 componentWillUnmount 生命周期函数的主要内容,如果未能解决你的问题,请参考以下文章
ZF_react hooks useEffect的实现 useRef useImperativeHandle的实现,react整体功能实现完毕