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