鉤子一直在席捲世界。在本教程中,我們將查看鉤子是什麼以及如何使用它們。我將向您介紹一些帶有React的常見鉤子,並向您展示如何編寫自己的鉤子。到完成時,您將能夠在自己的React Projects中使用鉤子。
。
如果我激起了您的好奇心,讓我們潛入並查看一些實際的例子。>先決條件
本教程旨在針對那些對什麼是反應及其工作方式有基本了解的人。如果您是React初學者,請在此處繼續進行React教程的開始。如果您想跟隨示例,則應該設置一個React應用程序。最簡單的方法是使用Create React App工具。為了使用此功能,您將安裝節點和NPM。如果您還沒有,請前往Node.js下載頁面並抓住系統的最新版本(NPM與Node捆綁在一起)。另外,您可以使用版本管理器諮詢我們的教程有關安裝節點的教程。
>安裝節點,您可以創建一個新的React應用程序:這將創建一個MyApp文件夾。更改此文件夾,然後像這樣啟動開發服務器:
>您的默認瀏覽器將打開,您會看到新的React應用程序。出於本教程的目的,您可以在位於src/app.js。
>您還可以在GitHub上找到本教程的代碼,以及本教程末尾完成的代碼的演示。
npx create-react-app myapp> USESTATE鉤
現在讓我們看一些代碼。 Usestate掛鉤可能是與React發貨的最常見鉤子。顧名思義,它允許您在函數組件中使用狀態。
<span>cd myapp </span><span>npm start </span>>
考慮以下REECT類組件:
如果您與Create React App一起關注,只需將App.js的內容替換為上述內容。
>給自己一分鐘以了解代碼。 在構造函數中,我們在狀態對像上聲明名稱屬性,並將HandlenAmeChange函數綁定到組件實例。然後,我們有一個帶有輸入的表單,其值設置為this.state.name。在this.state.name中持有的值也以問候的形式輸出到頁面。
<span>import <span>React</span> from "react"; </span> <span>export default class ClassDemo extends React<span>.Component</span> { </span> <span>constructor(props) { </span> <span>super(props); </span> <span>this.state = { </span> <span>name: "Agata" </span> <span>}; </span> <span>this.handleNameChange = this.handleNameChange.bind(this); </span> <span>} </span> <span>handleNameChange(e) { </span> <span>this.setState({ </span> <span>name: e.target.value </span> <span>}); </span> <span>} </span> <span>render() { </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={this.state.name} </span> onChange<span>={this.handleNameChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p>Hello {this.state.name}</p> </span> <span></section> </span> <span>); </span> <span>} </span><span>} </span>
用戶在輸入字段中鍵入任何內容時,稱為HandleNameChange函數,該功能更新狀態並因此是問候。
>現在,我們將使用Usestate Hook編寫此代碼的新版本。它的語法看起來像這樣:
npx create-react-app myapp
調用USESTATE函數時,它返回兩個項目:
請注意此功能版本和類版本之間的差異。它已經比班級版本更緊湊,更容易理解,但是他們倆都做了完全相同的事情。讓我們介紹差異:
<span>cd myapp </span><span>npm start </span>
>整個類構造函數已被Usestate Hook替換,該鉤僅由一條線組成。
>多個usestate鉤
>但是,如果我們想在州內聲明多個財產怎麼辦?沒問題。只需使用多個呼叫來進行USESESTATE。
這是一個具有多個usestate鉤子的組件的示例:
>
> useffect Hook大多數反應組件都需要執行特定操作,例如獲取數據,訂閱數據流或手動更改DOM。這類操作稱為副作用。
<span>import <span>React</span> from "react"; </span> <span>export default class ClassDemo extends React<span>.Component</span> { </span> <span>constructor(props) { </span> <span>super(props); </span> <span>this.state = { </span> <span>name: "Agata" </span> <span>}; </span> <span>this.handleNameChange = this.handleNameChange.bind(this); </span> <span>} </span> <span>handleNameChange(e) { </span> <span>this.setState({ </span> <span>name: e.target.value </span> <span>}); </span> <span>} </span> <span>render() { </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={this.state.name} </span> onChange<span>={this.handleNameChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p>Hello {this.state.name}</p> </span> <span></section> </span> <span>); </span> <span>} </span><span>} </span>> 在基於類的組件中,我們通常會將副作用代碼放入componentDidmount和componentDidupdate中。這些是生命週期方法,使我們能夠在正確的時間觸發渲染方法。
>
這是一個簡單的示例:npx create-react-app myapp
>此代碼將根據狀態中的內容設置文檔標題。但是,當您嘗試通過表單更改狀態值時,什麼也不會發生。要解決此問題,您需要添加另一種生命週期方法:
<span>cd myapp </span><span>npm start </span>
更新表單現在也應更新文檔標題。
>讓我們看看如何使用使用效果鉤實現相同的邏輯。更新上面的功能組件如下:
<span>import <span>React</span> from "react"; </span> <span>export default class ClassDemo extends React<span>.Component</span> { </span> <span>constructor(props) { </span> <span>super(props); </span> <span>this.state = { </span> <span>name: "Agata" </span> <span>}; </span> <span>this.handleNameChange = this.handleNameChange.bind(this); </span> <span>} </span> <span>handleNameChange(e) { </span> <span>this.setState({ </span> <span>name: e.target.value </span> <span>}); </span> <span>} </span> <span>render() { </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={this.state.name} </span> onChange<span>={this.handleNameChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p>Hello {this.state.name}</p> </span> <span></section> </span> <span>); </span> <span>} </span><span>} </span>
>只有那幾行代碼,我們在一個簡單函數中實現了兩種生命週期方法的工作。
>
<span>const [state, setState] = useState(initialState); </span>>上面的代碼將顯示瀏覽器窗口的當前分辨率。調整窗口的大小,您應該自動看到數字更新。如果您在Chrome中按
> f11,則應顯示顯示器的完整分辨率。我們還使用了componentWillunMount的生命週期方法來解開調整大小事件。
>讓我們在掛鉤版本中復制上述基於類的代碼。我們需要定義第三個Usestate鉤子和第二個使用效果掛鉤來處理這一新功能:
<span>import <span>React, { useState }</span> from "react"; </span> <span>export default function <span>HookDemo</span>(props) { </span> <span>const [name, setName] = useState("Agata"); </span> <span>function handleNameChange(e) { </span> <span>setName(e.target.value); </span> <span>} </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={name} </span> onChange<span>={handleNameChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p>Hello {name}</p> </span> <span></section> </span> <span>); </span><span>} </span>
>令人驚訝的是,該代碼的此掛鉤版本執行相同的操作。它更乾淨,更緊湊。將代碼放入其自己的使用效果聲明中的優點是,我們可以輕鬆測試它,因為代碼是孤立的。
>您是否注意到我們正在此使用效果掛鉤中返回功能?這是因為您在使用效果功能中返回的任何功能都將被視為清理代碼。如果您不返回功能,則不會進行清理。在這種情況下,需要進行清理,因為否則您會遇到登錄到瀏覽器控制台的錯誤消息,說“無法在未填充組件上執行React狀態更新”。
自定義React Hooks
>現在您已經了解了Usestate和使用效果掛鉤,讓我向您展示一種非常酷的方法,使您的代碼更加緊湊,更清潔和可重複使用,而不是我們到目前為止所取得的成就。我們將創建一個自定義掛鉤
以進一步簡化我們的代碼。創建一個新函數,如下所示:
接下來,在組件中,您需要替換此代碼:…與此:
<span>import <span>React, { useState }</span> from "react"; </span> <span>export default function <span>HookDemo</span>(props) { </span> <span>const [name, setName] = useState("Agata"); </span> <span>const [location, setLocation] = useState("Nairobi"); </span> <span>function handleNameChange(e) { </span> <span>setName(e.target.value); </span> <span>} </span> <span>function handleLocationChange(e) { </span> <span>setLocation(e.target.value); </span> <span>} </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={name} </span> onChange<span>={handleNameChange} </span> <span>/> </span> <span></section> </span> <span><section> </span> <span><label htmlFor="location">Location</label> </span> <span><input </span> type<span>="text" </span> name<span>="location" </span> id<span>="location" </span> value<span>={location} </span> onChange<span>={handleLocationChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p> </span> <span>Hello {name} from {location} </span> <span></p> </span> <span></section> </span> <span>); </span><span>} </span>刪除第二個使用效果代碼。保存文件並測試。一切都應該像以前一樣起作用。
>現在我們創建了第一個自定義掛鉤,讓我們為文檔標題做同樣的事情。首先,刪除剩餘的調用以在組件內的使用效果。然後,在組件之外,添加以下代碼:
>npx create-react-app myapp
最後,從組件中調用它:
<span>cd myapp </span><span>npm start </span>
>返回到您的瀏覽器,然後將某些內容輸入輸入字段。文檔標題應該像以前一樣更改。
最後,讓我們重構表單字段。我們想創建一個掛鉤,以使其值與狀態中的相應值保持同步。>讓我們從自定義掛鉤開始。添加組件的以下外部:
然後更新組件以使用它:
<span>import <span>React</span> from "react"; </span> <span>export default class ClassDemo extends React<span>.Component</span> { </span> <span>constructor(props) { </span> <span>super(props); </span> <span>this.state = { </span> <span>name: "Agata" </span> <span>}; </span> <span>this.handleNameChange = this.handleNameChange.bind(this); </span> <span>} </span> <span>handleNameChange(e) { </span> <span>this.setState({ </span> <span>name: e.target.value </span> <span>}); </span> <span>} </span> <span>render() { </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={this.state.name} </span> onChange<span>={this.handleNameChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p>Hello {this.state.name}</p> </span> <span></section> </span> <span>); </span> <span>} </span><span>} </span>
>慢慢瀏覽代碼,並確定我們所做的所有更改。很整潔,對吧?我們的組件要緊湊得多。
<span>const [state, setState] = useState(initialState); </span>為了本教程的目的,我們一直將鉤子聲明為與使用它們的組件相同的文件中的函數。但是,在一個普通的React項目中,您將在單獨的文件中使用每個掛鉤的掛鉤文件夾,然後可以將其導入所需的任何地方。
>我們甚至可以將UseFormInput,underOcumentTitle和useWindowResolution鉤打包到外部NPM模塊中,因為它們完全獨立於我們代碼的主要邏輯。我們可以輕鬆地在項目的其他部分,甚至將來其他項目重複使用這些自定義鉤子。
供參考,這是完整的掛鉤組件版本:
鉤的組件應呈現和表現與類組件版本完全一樣:
<span>import <span>React, { useState }</span> from "react"; </span> <span>export default function <span>HookDemo</span>(props) { </span> <span>const [name, setName] = useState("Agata"); </span> <span>function handleNameChange(e) { </span> <span>setName(e.target.value); </span> <span>} </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={name} </span> onChange<span>={handleNameChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p>Hello {name}</p> </span> <span></section> </span> <span>); </span><span>} </span>如果將掛鉤版本與類組件版本進行比較,則會意識到掛鉤功能將組件代碼降低至少30%。您甚至可以通過將可重複使用的功能導出到NPM庫來進一步降低代碼。
接下來,讓我們看一下如何在代碼中使用其他人的鉤子。
>讓我們看一個示例,說明如何使用Axios從REST JSON API中獲取數據並進行React Hooks獲取數據。如果您在家中關注,則需要安裝Axios庫:
更改您的組件看起來像這樣:
<span>import <span>React, { useState }</span> from "react"; </span> <span>export default function <span>HookDemo</span>(props) { </span> <span>const [name, setName] = useState("Agata"); </span> <span>const [location, setLocation] = useState("Nairobi"); </span> <span>function handleNameChange(e) { </span> <span>setName(e.target.value); </span> <span>} </span> <span>function handleLocationChange(e) { </span> <span>setLocation(e.target.value); </span> <span>} </span> <span>return ( </span> <span><section> </span> <span><form autoComplete="off"> </span> <span><section> </span> <span><label htmlFor="name">Name</label> </span> <span><input </span> type<span>="text" </span> name<span>="name" </span> id<span>="name" </span> value<span>={name} </span> onChange<span>={handleNameChange} </span> <span>/> </span> <span></section> </span> <span><section> </span> <span><label htmlFor="location">Location</label> </span> <span><input </span> type<span>="text" </span> name<span>="location" </span> id<span>="location" </span> value<span>={location} </span> onChange<span>={handleLocationChange} </span> <span>/> </span> <span></section> </span> <span></form> </span> <span><p> </span> <span>Hello {name} from {location} </span> <span></p> </span> <span></section> </span> <span>); </span><span>} </span>
>可以通過構建自己的自定義鉤子來重構上述代碼,例如我們不再需要使用USESTATE和使用效果掛鉤。對我們來說幸運的是,許多開發人員已經完成了這一任務,並發布了我們可以在項目中安裝的包裝的工作。我們將使用Simone Busoli的Axios-Hooks,這恰好是最受歡迎的。
您可以使用命令安裝軟件包:<span>componentDidMount() { </span> <span>document.title = this.state.name + " from " + this.state.location; </span><span>} </span>
npx create-react-app myapp
>下面,我使用Axios-Hooks重構上述代碼:
<span>cd myapp </span><span>npm start </span>>我們不僅擺脫了代碼中的Usestate和使用效果掛鉤,而且我們還獲得了三個新能力,沒有額外的大腦功率:
顯示加載狀態
demo
這些是您在日常的反應項目中會遇到的基本反應掛鉤:
>使用效果:替換生命週期功能
> USECALLBACK:返回一個返回可緩存值的函數。如果您想在輸入沒有更改時防止不必要的重新租用器,則對於性能優化很有用。
npx create-react-app myapp
您需要使用NPM或這樣的紗線安裝局部存儲掛鉤才能使用它:
<span>cd myapp </span><span>npm start </span>
很好,對嗎?
引入React Hooks引起了很大的飛濺。它的海浪已超越了React社區進入JavaScript世界。這是因為鉤子是一個可以使整個JavaScript生態系統受益的新概念。實際上,vue.js團隊最近發布了類似的作品API。
也有關於React Hooks和上下文API從其州管理王位推翻Redux的討論。顯然,掛鉤使編碼變得更加簡單,並改變了我們編寫新代碼的方式。如果您像我一樣,您可能有強烈的衝動重寫所有React組件類,並用功能性組件掛鉤替換它們。>請注意,這並不是真正的必要:React團隊不打算貶低React類組件。您還應該意識到,並非所有反應類生命週期方法都可以使用鉤子。您可能必須堅持使用React組件類別更長的時間。
>如果您對基本反應鉤的新知識充滿信心,我想給您帶來挑戰。重構此倒數計時器類使用React鉤子,使其盡可能清潔和緊湊。
愉快的編碼,讓我知道您如何進行!> REECT HOCKS上的FAQ
>
為什麼引入了React Hooks?引入了React鉤子,以簡化功能組件中狀態邏輯的重複使用,從而更容易管理組件狀態和副作用。鉤?
>您可以使用USESTATE掛鉤將狀態添加到功能組件中。它返回具有當前狀態值的數組和更新它的功能。使用效果掛鉤允許您在功能組件中執行副作用,例如數據獲取,DOM操縱等,並確保正確處理這些效果。
>我可以使用多個>單個組件中的USESTATE和使用效果掛鉤?
是的,您可以在單個功能組件中使用多個Usestate和使用效果鉤的實例來管理不同的狀態和效果。>用戶掛鉤是用於更複雜狀態管理的Usestate的替代方法。當您需要以可預測的方式管理狀態轉換時,這很有用。
您可以通過定義使用內置鉤或其他自定義鉤的功能來創建自定義鉤。這些自定義掛鉤可以跨組件封裝並共享狀態邏輯。>在React中使用鉤子的規則是什麼?
使用掛鉤的關鍵規則僅包括在功能組件中使用它們,使用頂層的鉤子(不是內部環或條件),並確保它們在組件中的順序在重新租用器上保持一致。> React鉤有任何性能考慮嗎?
正確使用時,React鉤子可以通過減少不必要的重新租賃來提高性能。但是,必須使用USEMEMO和USECALLBACK掛鉤在需要時優化性能。以上是React Hooks:如何開始並建立自己的的詳細內容。更多資訊請關注PHP中文網其他相關文章!