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.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM