在寫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.com</h2>;
}
function List() {
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.com</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.com</h2>;
}
這時候你在瀏覽器中預覽,我們仿佛實現了componentWillUnmount方法。但這只是好像實現了,當點擊計數器按鈕時,你會發現老弟,你走了!Index頁面,也出現了。這到底是怎么回事那?其實每次狀態發生變化,useEffect都進行了解綁。
useEffect的第二個參數
那到底要如何實現類似componentWillUnmount的效果那?這就需要請出useEffect的第二個參數,它是一個數組,數組中可以寫入很多狀態對應的變量,意思是當狀態值發生變化時,我們才進行解綁。但是當傳空數組[]時,就是當組件將被銷毀時才進行解綁,這也就實現了componentWillUnmount的生命周期函數。
function Index() {
useEffect(()=>{
console.log('useEffect=>老弟你來了!Index頁面')
return ()=>{
console.log('老弟,你走了!Index頁面')
}
},[])
return <h2>JSPang.com</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狀態發生變化,都會執行解綁副作用函數,瀏覽器的控制台也就打印出了一串=================。
轉自:https://jspang.com/posts/2019/08/12/react-hooks.html
