在寫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