摘要:簡(jiǎn)介是的新增特性。我們統(tǒng)一把這些操作稱為副作用,或者簡(jiǎn)稱為作用。由于副作用函數(shù)是在組件內(nèi)聲明的,所以它們可以訪問(wèn)到組件的和。副作用函數(shù)還可以通過(guò)返回一個(gè)函數(shù)來(lái)指定如何清除副作用。目前為止,有兩種主流方案來(lái)解決這個(gè)問(wèn)題高階組件和。
Hook 簡(jiǎn)介
Hook 是 React 16.8 的新增特性。它可以讓你在不編寫(xiě) class 的情況下使用 state 以及其他的 React 特性。
useState這個(gè)例子用來(lái)顯示一個(gè)計(jì)數(shù)器。當(dāng)你點(diǎn)擊按鈕,計(jì)數(shù)器的值就會(huì)增加:
import React, { useState } from "react"; function Example() { // 聲明一個(gè)新的叫做 “count” 的 state 變量 const [count, setCount] = useState(0); return (); }You clicked {count} times
useState 唯一的參數(shù)就是初始 state。在上面的例子中,我們的計(jì)數(shù)器是從零開(kāi)始的,所以初始 state 就是 0。
聲明多個(gè) state 變量你可以在一個(gè)組件中多次使用 State Hook:
function ExampleWithManyStates() { // 聲明多個(gè) state 變量! const [age, setAge] = useState(42); const [fruit, setFruit] = useState("banana"); const [todos, setTodos] = useState([{ text: "Learn Hooks" }]); // ... }Effect Hook
你之前可能已經(jīng)在 React 組件中執(zhí)行過(guò)數(shù)據(jù)獲取、訂閱或者手動(dòng)修改過(guò) DOM。我們統(tǒng)一把這些操作稱為“副作用”,或者簡(jiǎn)稱為“作用”。
useEffect 就是一個(gè) Effect Hook,給函數(shù)組件增加了操作副作用的能力。它跟 class 組件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不過(guò)被合并成了一個(gè) API。
可以通知 React 跳過(guò)對(duì) effect 的調(diào)用,只要傳遞數(shù)組作為 useEffect 的第二個(gè)可選參數(shù)即可:
例如,下面這個(gè)組件在 React 更新 DOM 后會(huì)設(shè)置一個(gè)頁(yè)面標(biāo)題:
import React, { useState, useEffect } from "react"; function Example() { const [count, setCount] = useState(0); // 相當(dāng)于 componentDidMount 和 componentDidUpdate: useEffect(() => { // 使用瀏覽器的 API 更新頁(yè)面標(biāo)題 document.title = `You clicked ${count} times`; }[count]); // 僅在 count 更改時(shí)更新 return (); }You clicked {count} times
當(dāng)你調(diào)用 useEffect 時(shí),就是在告訴 React 在完成對(duì) DOM 的更改后運(yùn)行你的“副作用”函數(shù)。由于副作用函數(shù)是在組件內(nèi)聲明的,所以它們可以訪問(wèn)到組件的 props 和 state。默認(rèn)情況下,React 會(huì)在每次渲染后調(diào)用副作用函數(shù) —— 包括第一次渲染的時(shí)候。
副作用函數(shù)還可以通過(guò)返回一個(gè)函數(shù)來(lái)指定如何“清除”副作用。例如,在下面的組件中使用副作用函數(shù)來(lái)訂閱好友的在線狀態(tài),并通過(guò)取消訂閱來(lái)進(jìn)行清除操作:
import React, { useState, useEffect } from "react"; function FriendStatus(props) { const [isOnline, setIsOnline] = useState(null); function handleStatusChange(status) { setIsOnline(status.isOnline); } useEffect(() => { ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); return () => { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; }); if (isOnline === null) { return "Loading..."; } return isOnline ? "Online" : "Offline"; }
在這個(gè)示例中,React 會(huì)在組件銷毀或者后續(xù)渲染重新執(zhí)行副作用函數(shù)時(shí)取消對(duì) ChatAPI 的訂閱。(如果傳給 ChatAPI 的 props.friend.id 沒(méi)有變化,你也可以告訴 React 跳過(guò)重新訂閱。)
Hook 使用規(guī)則Hook 就是 JavaScript 函數(shù),但是使用它們會(huì)有兩個(gè)額外的規(guī)則:
只能在函數(shù)最外層調(diào)用 Hook。不要在循環(huán)、條件判斷或者子函數(shù)中調(diào)用。
只能在 React 的函數(shù)組件中調(diào)用 Hook。不要在其他 JavaScript 函數(shù)中調(diào)用。
自定義 Hook有時(shí)候我們會(huì)想要在組件之間重用一些狀態(tài)邏輯。目前為止,有兩種主流方案來(lái)解決這個(gè)問(wèn)題:高階組件和 render props。自定義 Hook 可以讓你在不增加組件的情況下達(dá)到同樣的目的。
前面,我們介紹了一個(gè)叫 FriendStatus 的組件,它通過(guò)調(diào)用 useState 和 useEffect 的 Hook 來(lái)訂閱一個(gè)好友的在線狀態(tài)。假設(shè)我們想在另一個(gè)組件里重用這個(gè)訂閱邏輯。
首先,我們把這個(gè)邏輯抽取到一個(gè)叫做 useFriendStatus 的自定義 Hook 里:
import React, { useState, useEffect } from "react"; function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); function handleStatusChange(status) { setIsOnline(status.isOnline); } useEffect(() => { ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange); return () => { ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange); }; }); return isOnline; }
它將 friendID 作為參數(shù),并返回該好友是否在線:
現(xiàn)在我們可以在兩個(gè)組件中使用它:
function FriendStatus(props) { const isOnline = useFriendStatus(props.friend.id); if (isOnline === null) { return "Loading..."; } return isOnline ? "Online" : "Offline"; } function FriendListItem(props) { const isOnline = useFriendStatus(props.friend.id); return (
這兩個(gè)組件的 state 是完全獨(dú)立的。Hook 是一種復(fù)用狀態(tài)邏輯的方式,它不復(fù)用 state 本身。事實(shí)上 Hook 的每次調(diào)用都有一個(gè)完全獨(dú)立的 state —— 因此你可以在單個(gè)組件中多次調(diào)用同一個(gè)自定義 Hook。
自定義 Hook 更像是一種約定而不是功能。如果函數(shù)的名字以 “use” 開(kāi)頭并調(diào)用其他 Hook,我們就說(shuō)這是一個(gè)自定義 Hook。
其他HooksuseReducer
useState 的替代方案。它接收一個(gè)形如 (state, action) => newState 的 reducer,并返回當(dāng)前的 state 以及與其配套的 dispatch 方法。(如果你熟悉 Redux 的話,就已經(jīng)知道它如何工作了。)
在某些場(chǎng)景下,useReducer 會(huì)比 useState 更適用,例如 state 邏輯較復(fù)雜且包含多個(gè)子值,或者下一個(gè) state 依賴于之前的 state 等。并且,使用 useReducer 還能給那些會(huì)觸發(fā)深更新的組件做性能優(yōu)化,因?yàn)槟憧梢韵蜃咏M件傳遞 dispatch 而不是回調(diào)函數(shù) 。
以下是用 reducer 重寫(xiě) useState 計(jì)數(shù)器示例:
const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case "increment": return {count: state.count + 1}; case "decrement": return {count: state.count - 1}; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} > ); }
useContext
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109928.html
摘要:最近官方在大會(huì)上宣布內(nèi)測(cè)將引入。所以我們有必要了解,以及由此引發(fā)的疑問(wèn)。在進(jìn)一步了解之前,我們需要先快速的了解一些基本的的用法。如何解決狀態(tài)有關(guān)的邏輯的重用和共享問(wèn)題。 showImg(https://segmentfault.com/img/remote/1460000016886798?w=1500&h=750); 大家好,我是谷阿莫,今天要將的是一個(gè)...,哈哈哈,看到這個(gè)題我就...
摘要:所以我們做的事情其實(shí)就是,聲明了一個(gè)狀態(tài)變量,把它的初始值設(shè)為,同時(shí)提供了一個(gè)可以更改的函數(shù)。 你還在為該使用無(wú)狀態(tài)組件(Function)還是有狀態(tài)組件(Class)而煩惱嗎? ——擁有了hooks,你再也不需要寫(xiě)Class了,你的所有組件都將是Function。 你還在為搞不清使用哪個(gè)生命周期鉤子函數(shù)而日夜難眠嗎? ——擁有了Hooks,生命周期鉤子函數(shù)可以先丟一邊了。 你在還...
摘要:使用該對(duì)象,可以跟蹤屬于組件的各種元數(shù)據(jù)位。調(diào)用你的組件這意味著它知道存儲(chǔ)的元數(shù)據(jù)對(duì)象。下一次渲染會(huì)發(fā)生什么需要重新渲染組件由于之前已經(jīng)看過(guò)這個(gè)組件,它已經(jīng)有了元數(shù)據(jù)關(guān)聯(lián)。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 我們大部分 React 類組件可以保存狀態(tài),而函數(shù)組件不能? 并且類組件具有生命周期,而函數(shù)組件卻不能...
摘要:課程制作和案例制作都經(jīng)過(guò)精心編排。對(duì)于開(kāi)發(fā)者意義重大,希望對(duì)有需要的開(kāi)發(fā)者有所幫助。是從提案轉(zhuǎn)為正式加入的新特性。并不需要用繼承,而是推薦用嵌套。大型項(xiàng)目中模塊化與功能解耦困難。從而更加易于復(fù)用和獨(dú)立測(cè)試。但使用會(huì)減少這種幾率。 showImg(https://segmentfault.com/img/bVbpNRZ?w=1920&h=1080); 講師簡(jiǎn)介 曾任職中軟軍隊(duì)事業(yè)部,參與...
摘要:第一個(gè)功能是普通經(jīng)典類組件,也就是眾所周知的有狀態(tài)組件。我們準(zhǔn)備創(chuàng)建一個(gè)上下文環(huán)境來(lái)存放全局狀態(tài),然后把它的包裹在一個(gè)有狀態(tài)組件中,然后用來(lái)管理狀態(tài)。接下來(lái)我們需要用有狀態(tài)組件包裹我們的,利用它進(jìn)行應(yīng)用狀態(tài)的管理。 原文地址對(duì)于想要跳過(guò)文章直接看結(jié)果的人,我已經(jīng)把我寫(xiě)的內(nèi)容制作成了一個(gè)庫(kù):use-simple-state,無(wú)任何依賴(除了依賴 react ),只有3kb,相當(dāng)輕量。 ...
閱讀 2973·2023-04-26 02:29
閱讀 585·2019-08-30 15:54
閱讀 1658·2019-08-29 13:13
閱讀 600·2019-08-28 17:51
閱讀 2722·2019-08-26 13:58
閱讀 1531·2019-08-26 13:27
閱讀 2819·2019-08-26 11:39
閱讀 3445·2019-08-26 10:46