React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount問題
介紹
Hook 是 React 16.8 的新增特性。
它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。
緣由
Hook的初衷是為了解決原本無狀態(tài)組建需要使用state, 必須改造為class這個痛點.
useState
import React, { useState } from 'react'; function Example() { // 聲明一個叫 "count" 的 state 變量 const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
這個是官方提供的最簡單的例子.
不難理解, 按鈕每次點擊都會調(diào)用一次setCount, 從而改變count的值
和以下的例子等價
class Example extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> Click me </button> </div> ); } }
我用注釋來解釋可能更好理解useState每個參數(shù)的意義,稍微改造一下第一個例子
import React, { useState } from 'react'; function Example() { // 聲明一個叫 "count" 的 state 變量 const [ count, // 在state里面的名字 setCount // 改變這個名字的函數(shù) ] = useState( 0 // 初值count的初值 ); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount( count + 1 // 準備把count該成什么樣子 )}> Click me </button> </div> ); }
在以前class的形式, 所有的可變數(shù)據(jù)都放在一個state內(nèi)部進行維護, 這樣這個state會越來越大…越來越臃腫…越來越難以維護…如果沒有注釋可能就難以理解…這樣就誕生了Redux
我本人認為, useState可以直接解決這樣的一個痛點, 下面是我在新項目中使用hook的例子
// 表格loading const [loading, setLoading] = useState(true); // 表格數(shù)據(jù) const [listData, setListData] = useState({ list: [], total: 0 }); // 當前頁碼 const [current, setCurrent] = useState(0); // 搜索數(shù)據(jù) const [searchData, setSearchData] = useState({}); // 醫(yī)生職稱 const [jobTitle, setJobTitle] = useState([]); // 科室 const [dept, setDept] = useState([]); // 彈窗顯隱 const [visible, setVisible] = useState(false); // 彈窗數(shù)據(jù) const [showData, setShowData] = useState({});
可以很直觀的看到基本上一個數(shù)據(jù)享受一個useState…配合正確的注釋, 調(diào)用正確的方法, 使代碼可讀性大大增強.
useEffect
如果你熟悉 React class 的生命周期函數(shù),你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個函數(shù)的組合。
這句話來自官網(wǎng)的原畫.
接下來我就為大家解釋useEffect
useEffect 會在每次渲染后都執(zhí)行嗎? 是的,默認情況下,它在第一次渲染之后和每次更新之后都會執(zhí)行。
這個是官網(wǎng)的原話, 不難理解,這樣就可以模擬出componentDidUpdate…你可以在hook里面寫你想要邏輯. .
直接上官網(wǎng)代碼
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
可以看到每次點擊按鈕, 都重新set了Count的值, 因為每次更新都會走到useEffect(后面會說到怎么樣不每次都進入useEffect ).他是useEffect的邏輯是,每次都修改document.title
這樣就模擬了componentDidUpdate
componentDidMount componentWillUnmount
useEffect其實有兩個參數(shù), 第一個是調(diào)用函數(shù), 第二個是監(jiān)聽值.
useEffect( () => { // 我叫A函數(shù) const subscription = props.source.subscribe(); return () => { subscription.unsubscribe(); }; }, [props.source], );
這段代碼可以理解為, 程序一運行, 就調(diào)用了一次A函數(shù),之后每次渲染雖然都會走到這個useEffect. 因為他有第二個參數(shù).所以只有在 [props.source]
變化的時候.才會再次調(diào)用A函數(shù).
我們可以靈活的調(diào)用起來, 這個值可以來自useState控制.你想他變化的時候,你就用useState改變一下他的值.
最典型的例子就是, 短信的倒計時
那我怎么樣才可以優(yōu)雅的讓這個useEffect只調(diào)用一次.像componentDidMount呢?
可以這樣在第二個值傳一個控制進去.
useEffect(() => { const firstGet = async () => { const [z, x, c] = await Promise.all([ requestZ(), requestX(), requestZ(), ]); // 做你想做的事情 }; firstGet(); }, []);
這樣就可以很優(yōu)雅的模仿componentDidMount.而不需要在后面搞什么沒人知道的花里胡哨的值.
那怎么樣才可以模仿componentWillUnmount呢?
useEffect(() => { // Specify how to clean up after this effect: return function cleanup() { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; }, []);
為什么要在 effect 中返回一個函數(shù)? 這是 effect 可選的清除機制。每個 effect 都可以返回一個清除函數(shù)。如此可以將添加和移除訂閱的邏輯放在一起。它們都屬于 effect 的一部分。
React 何時清除 effect? React 會在組件卸載的時候執(zhí)行清除操作。正如之前學(xué)到的,effect 在每次渲染的時候都會執(zhí)行。這就是為什么 React 會在執(zhí)行當前 effect 之前對上一個 effect 進行清除。
這些都是官網(wǎng)的原話. 代碼中的return 就是清除…同樣的,在第二個值放入一個空.這樣就會很優(yōu)雅的清除了. 最明顯就是短信倒計時的setInerval
, clear一下才不會一直占用資源
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
React操作真實DOM實現(xiàn)動態(tài)吸底部的示例
本篇文章主要介紹了React操作真實DOM實現(xiàn)動態(tài)吸底部的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10reset.css瀏覽器默認樣式表重置(user?agent?stylesheet)的示例代碼
這篇文章主要介紹了reset.css瀏覽器默認樣式表重置(user?agent?stylesheet),本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-12-12React報錯Element type is invalid解決案例
這篇文章主要為大家介紹了React報錯Element type is invalid解決案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12useEffect如何通過form.getFieldValue(‘xxx‘)監(jiān)聽Form表單變化
這篇文章主要介紹了useEffect如何通過form.getFieldValue(‘xxx‘)監(jiān)聽Form表單變化問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03React實現(xiàn)Excel文件的導(dǎo)出與在線預(yù)覽功能
這篇文章主要為大家詳細介紹了如何利用?React?18?的強大功能,演示如何使用?React?18?編寫?Excel?文件的導(dǎo)出與在線預(yù)覽功能,需要的小伙伴可以參考下2023-12-12React?Context?變遷及背后實現(xiàn)原理詳解
這篇文章主要為大家介紹了React?Context?變遷及背后實現(xiàn)原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11