摘要:組件的職責(zé)增長并變得不可分割。是架構(gòu)的重要組成部分。有許多好處,但它們?yōu)槌鯇W(xué)者創(chuàng)造了入門的障礙。方法使用狀態(tài)鉤子的最好方法是對(duì)其進(jìn)行解構(gòu)并設(shè)置原始值。第一個(gè)參數(shù)將用于存儲(chǔ)狀態(tài),第二個(gè)參數(shù)用于更新狀態(tài)。
學(xué)習(xí)目標(biāo)
在本文結(jié)束時(shí),您將能夠回答以下問題:
什么是 hooks?
如何使用hooks?
使用hooks的一些規(guī)則?
什么是custom hook(自定義鉤子)?
什么時(shí)候應(yīng)該使用 custom hooks?
使用 custom hooks有什么好處?
什么是 hooks?Hooks 可以做到以下事情:
在功能組件中使用state和“hook into”的生命周期方法。
在組件之間重用有狀態(tài)邏輯,這簡(jiǎn)化了組件邏輯,最重要的是,讓你跳過編寫classes。
如果你已經(jīng)使用過React,你就會(huì)知道復(fù)雜多變,有狀態(tài)的邏輯是如何得到的,當(dāng)應(yīng)用程序?yàn)楣δ芴砑恿藥讉€(gè)新功能時(shí),就會(huì)發(fā)生組件代碼變得復(fù)雜而難以維護(hù)這種情況。為了嘗試簡(jiǎn)化這個(gè)問題,React背后的大腦試圖找到解決這個(gè)問題的方法。
(1) 在組件之間重用有狀態(tài)邏輯
hooks允許開發(fā)人員編寫簡(jiǎn)單,有狀態(tài)的功能組件,并在開發(fā)時(shí)花費(fèi)更少的時(shí)間來設(shè)計(jì)和重構(gòu)組件層次結(jié)構(gòu)。怎么樣?使用鉤子,您可以在組件之間_獲取_和_分享_有狀態(tài)邏輯。
(2) 簡(jiǎn)化組件邏輯
當(dāng)您的應(yīng)用程序中出現(xiàn)不可避免的指數(shù)級(jí)邏輯增長時(shí),簡(jiǎn)單的組件就回因?yàn)楦鞣N狀態(tài)邏輯和生命周期等等因素,而變得繁瑣和復(fù)雜。組件的職責(zé)增長并變得不可分割。反過來,這使編碼變得麻煩并且測(cè)試?yán)щy。
class是React架構(gòu)的重要組成部分。class有許多好處,但它們?yōu)槌鯇W(xué)者創(chuàng)造了入門的障礙。對(duì)于class,您還必須記住將this綁定到事件處理程序,因此代碼可能變得冗長且有點(diǎn)多余。
如何使用hooks?React版本 16.8.
import { useState, useEffect } from "react";
很簡(jiǎn)單,但你如何實(shí)際使用這些新方法?以下示例非常簡(jiǎn)單,但這些方法的功能非常強(qiáng)大。
useState hook方法使用狀態(tài)鉤子(state hook)的最好方法是對(duì)其進(jìn)行解構(gòu)并設(shè)置原始值。第一個(gè)參數(shù)將用于存儲(chǔ)狀態(tài),第二個(gè)參數(shù)用于更新狀態(tài)。
例如:
const [weight, setWeight] = useState(150); onClick={() => setWeight(weight + 15)}
weight是狀態(tài)
setWeight是一種用于更新狀態(tài)的方法
useState(150)是用于設(shè)置初始值(任何基本類型)的方法
值得注意的是,您可以在單個(gè)組件中多次構(gòu)造狀態(tài)hook:
const [age, setAge] = useState(42); const [month, setMonth] = useState("February"); const [todos, setTodos] = useState([{ text: "Eat pie" }]);
因此,該組件可能看起來像:
import React, { useState } from "react"; export default function App() { const [weight, setWeight] = useState(150); const [age] = useState(42); const [month] = useState("February"); const [todos] = useState([{ text: "Eat pie" }]); return ( Current Weight: {weight} Age: {age} Month: {month} setWeight(weight + 15)}> {todos[0].text} ); }useEffect鉤子方法
使用effect hook 就好像使用componentDidMount, componentDidUpdate, 和 componentWillUnmount這類的生命周期的方法。
例如:
// similar to the componentDidMount and componentDidUpdate methods useEffect(() => { document.title = You clicked ${count} times; });
組件更新的任何時(shí)候,渲染后都會(huì)調(diào)用useEffect?,F(xiàn)在,如果你只想在變量count改變時(shí)更新useEffect,你只需將該事實(shí)添加到數(shù)組中方法的末尾,類似于高階reduce方法末尾的累加器。
// check out the variable count in the array at the end... useEffect(() => { document.title = You clicked ${count} times; }, [ count ]);
讓我們結(jié)合兩個(gè)例子:
const [weight, setWeight] = useState(150); useEffect(() => { document.title = You weigh ${weight}, you ok with that?; }, [ weight ]); onClick={() => setWeight(weight + 15)}
因此,當(dāng)觸發(fā)onClick時(shí),也會(huì)調(diào)用useEffect方法,并在DOM更新后在文檔標(biāo)題中呈現(xiàn)新的數(shù)據(jù)。
例:
import React, { useState, useEffect } from "react"; export default function App() { const [weight, setWeight] = useState(150); const [age] = useState(42); const [month] = useState("February"); const [todos] = useState([{ text: "Eat pie" }]); useEffect(() => { document.title = You weigh ${weight}, you ok with that?; }); return ( Current Weight: {weight} Age: {age} Month: {month} setWeight(weight + 15)}> {todos[0].text} ); }
useEffect非常適合進(jìn)行API調(diào)用:
useEffect(() => { fetch("https://jsonplaceholder.typicode.com/todos/1") .then(results => results.json()) .then((data) => { setTodos([{ text: data.title }]); }); }, []);
React鉤子看起來很棒,但是如果你花一點(diǎn)時(shí)間,你可能會(huì)意識(shí)到在多個(gè)組件中重新初始化多個(gè)鉤子方法,比如useState和useEffect,可能會(huì)違背DRY(Don"t repeat yourself)原則。那么,讓我們看看如何通過創(chuàng)建自定義鉤子來重用這些新內(nèi)置方法。
關(guān)于使用hooks的一些規(guī)則?是的,React鉤子有規(guī)則。這些規(guī)則乍一看似乎是非常規(guī)的,但是一旦你理解了React鉤子如何啟動(dòng)的基礎(chǔ)知識(shí),規(guī)則就很容易理解。
(1) 必須在頂層以相同的順序調(diào)用掛鉤。(依次調(diào)用)
Hooks創(chuàng)建一個(gè)鉤子調(diào)用數(shù)組來保持秩序。這個(gè)命令有助于React告訴區(qū)別,例如,在單個(gè)組件中或跨應(yīng)用程序的多個(gè)useState和useEffect方法調(diào)用之間。
例如:
// This is good! function ComponentWithHooks() { // top-level! const [age, setAge] = useState(42); const [month, setMonth] = useState("February"); const [todos, setTodos] = useState([{ text: "Eat pie" }]); return ( //... ) }
在第一次渲染時(shí),42,F(xiàn)ebruary,[{text:"Eat pie"}]都被推入狀態(tài)數(shù)組。
當(dāng)組件重新渲染時(shí),忽略u(píng)seState方法參數(shù)。
age,month和todos的值是從組件的狀態(tài)中檢索的,這是前面提到的狀態(tài)數(shù)組。
(2) 無法在條件語句或循環(huán)中調(diào)用掛鉤。
由于啟動(dòng)hooks的方式,不允許使用within條件語句或循環(huán)。對(duì)于hooks,如果在重新渲染期間初始化的順序發(fā)生變化,則很可能您的應(yīng)用程序無法正常運(yùn)行。您仍然可以在組件中使用條件語句和循環(huán),但不能在代碼塊內(nèi)使用鉤子。
例如:
// DON"T DO THIS!! const [DNAMatch, setDNAMatch] = useState(false) if (name) { setDNAMatch(true) const [name, setName] = useState(name) useEffect(function persistFamily() { localStorage.setItem("dad", name); }, []); } // DO THIS!! const [DNAMatch, setDNAMatch] = useState(false) const [name, setName] = useState(null) useEffect(() => { if (name) { setDNAMatch(true) setName(name) localStorage.setItem("dad", name); } }, []);
(3) 鉤子不能用在class組件中。
鉤子必須在功能組件或自定義鉤子函數(shù)中初始化。自定義鉤子函數(shù)只能在功能組件中調(diào)用,并且必須遵循與非自定義鉤子相同的規(guī)則。
您仍然可以在同一個(gè)應(yīng)用程序中使用類組件。您可以使用hooks作為類組件的子項(xiàng)呈現(xiàn)功能組件。
(4) 自定義鉤子應(yīng)該以單詞use開頭并且是駝峰式的。
這是一個(gè)強(qiáng)有力的建議而非規(guī)則,但它將有助于您的應(yīng)用程序的一致性。你也會(huì)知道,當(dāng)你看到一個(gè)以“use”為前綴的函數(shù)時(shí),它可能是一個(gè)自定義鉤子。
自定義掛鉤只是遵循與非自定義掛鉤相同規(guī)則的函數(shù)。它們?cè)试S您整合邏輯,共享數(shù)據(jù)以及跨組件重用鉤子。
什么時(shí)候應(yīng)該使用自定義hook?當(dāng)您需要在組件之間共享邏輯時(shí),最好使用自定義掛鉤。在JavaScript中,當(dāng)您想要在兩個(gè)多帶帶的函數(shù)之間共享邏輯時(shí),您可以創(chuàng)建另一個(gè)函數(shù)來支持它。好吧,就像組件一樣,hooks也是function。您可以提取hooks邏輯,以便在應(yīng)用程序的組件之間共享。在編寫自定義hooks時(shí),您可以命名它們(再次以“use”開頭),設(shè)置參數(shù),并告訴它們應(yīng)該返回什么(如果有的話)。
例如:
import { useEffect, useState } from "react"; const useFetch = ({ url, defaultData = null }) => { const [data, setData] = useState(defaultData); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(url) .then(res => res.json()) .then((res) => { setData(res); setLoading(false); }) .catch((err) => { setError(err); setLoading(false); }); }, []); const fetchResults = { data, loading, error, }; return fetchResults; }; export default useFetch;使用自定義hook有什么好處?
Hooks允許您在應(yīng)用程序增長時(shí)抑制復(fù)雜性,并編寫更易于理解的代碼。下面的代碼是兩個(gè)具有相同功能的組件的比較。在第一次比較之后,我們將在伴隨容器的組件中使用自定義鉤子展示更多好處。
以下類組件應(yīng)該看起來:
import React from "react"; class OneChanceButton extends React.Component { constructor(props) { super(props); this.state = { clicked: false, }; this.handleClick = this.handleClick.bind(this); } handleClick() { return this.setState({ clicked: true }); } render() { return ( You Have One Chance to Click ); } } export default OneChanceButton;
如何使用鉤子實(shí)現(xiàn)相同的功能來簡(jiǎn)化代碼并提高可讀性:
import React, { useState } from "react"; function OneChanceButton(props) { const [clicked, setClicked] = useState(false); function doClick() { return setClicked(true); } return ( You Have One Chance to Click ); } export default OneChanceButton;結(jié)論
React hooks是一個(gè)驚人的新功能!實(shí)施的理由是合理的;并且,再加上這一點(diǎn),我相信這將極大地降低React編碼的門檻,并使其保持在最喜歡的框架之上列表??吹竭@會(huì)如何改變第三方庫的工作方式,尤其是狀態(tài)管理工具和路由器,將會(huì)非常令人興奮。
總之,React鉤子:
無需使用類組件即可輕松與React的生命周期方法相關(guān)聯(lián)
通過增加可重用性和抽象復(fù)雜性來幫助減少代碼量
幫助簡(jiǎn)化組件之間共享數(shù)據(jù)的方式
推薦閱讀:https://juejin.im/post/5be8d3...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/54024.html
摘要:前言樓主最近在整理的一些資料,為項(xiàng)目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個(gè)初始值,比如,這個(gè)按鈕的最初要顯示的是。取代了提供了一個(gè)統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...
摘要:前言樓主最近在整理的一些資料,為項(xiàng)目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個(gè)初始值,比如,這個(gè)按鈕的最初要顯示的是。取代了提供了一個(gè)統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...
摘要:當(dāng)組件安裝和更新時(shí),回調(diào)函數(shù)都會(huì)被調(diào)用。好在為我們提供了第二個(gè)參數(shù),如果第二個(gè)參數(shù)傳入一個(gè)數(shù)組,僅當(dāng)重新渲染時(shí)數(shù)組中的值發(fā)生改變時(shí),中的回調(diào)函數(shù)才會(huì)執(zhí)行。 前言 首先歡迎大家關(guān)注我的Github博客,也算是對(duì)我的一點(diǎn)鼓勵(lì),畢竟寫東西沒法獲得變現(xiàn),能堅(jiān)持下去也是靠的是自己的熱情和大家的鼓勵(lì),希望大家多多關(guān)注呀!React 16.8中新增了Hooks特性,并且在React官方文檔中新增...
摘要:到目前為止,表達(dá)這種流程的基本形式是課程。按鈕依次響應(yīng)并更改獲取更新的文本。事實(shí)證明不能從返回一個(gè)。可以在組件中使用本地狀態(tài),而無需使用類。替換了提供統(tǒng)一,和。另一方面,跟蹤中的狀態(tài)變化確實(shí)很難。 備注:為了保證的可讀性,本文采用意譯而非直譯。 在這個(gè) React鉤子 教程中,你將學(xué)習(xí)如何使用 React鉤子,它們是什么,以及我們?yōu)槭裁催@樣做! showImg(https://segm...
摘要:課程制作和案例制作都經(jīng)過精心編排。對(duì)于開發(fā)者意義重大,希望對(duì)有需要的開發(fā)者有所幫助。是從提案轉(zhuǎn)為正式加入的新特性。并不需要用繼承,而是推薦用嵌套。大型項(xiàng)目中模塊化與功能解耦困難。從而更加易于復(fù)用和獨(dú)立測(cè)試。但使用會(huì)減少這種幾率。 showImg(https://segmentfault.com/img/bVbpNRZ?w=1920&h=1080); 講師簡(jiǎn)介 曾任職中軟軍隊(duì)事業(yè)部,參與...
閱讀 2008·2019-08-29 16:27
閱讀 1379·2019-08-29 16:14
閱讀 3380·2019-08-29 14:18
閱讀 3463·2019-08-29 13:56
閱讀 1261·2019-08-29 11:13
閱讀 2131·2019-08-28 18:19
閱讀 3450·2019-08-27 10:57
閱讀 2287·2019-08-26 11:39