亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用useReducer Hook

發布時間:2020-05-23 15:03:45 來源:網絡 閱讀:347 作者:可樂程序員 欄目:web開發

看到“reducer”這個詞,容易讓人聯想到Redux,但是在本文中,不必先理解Redux才能閱讀這篇文章。咱們將一起討論“reducer”實際上是什么,以及如何利用useReducer來管理組件中的復雜狀態,以及這個新鉤子對Redux意味著什么?

Reducer 是什么鬼

如果你熟悉Redux或數組上中的reduce方法,你大概就知道“reducer”是什么。 如果不熟悉,“reducer”大概是一個帶有2個值并返回1個值的函數這么個意思。

如果你有一系列的東西,并且想將這些東西組合成一個單獨的物體。“函數式編程”中就是使用Array的reduce函數。 例如,如果你有一個數字數組并且想得到數組中所有數字的總和,咱們就可以寫一個reducer函數并將它傳遞給reduce,如下所示:

let?numbers?=?[1,?2,?3];
let?sum?=?numbers.reduce((total,?number)?=>?{
?return?total?+?number;
},0)
復制代碼

如果你以前沒用過這個,它可能看起來有點神秘。它所做的是為數組的每個元素調用函數,傳入前一個total和當前元素 number。無論你返回什么,都會成為新的total。reduce的第二個參數(在本例中為0)是total的初始值。在本例中,reduce函數會被調用3次:

  • 調用 (0, 1) 返回 1

  • 調用 (1, 2) 返回 3

  • 調用 (3, 4) 返回 6

reduce返回6,它保存在sum中。

使用useReducer又會是什么樣的?

各位花了在半篇幅來解釋Array的reduce函數,因為 useReducer 參數與 reduce 相同,并且工作方式基本一樣。 useReducer接收 (state, action) => newState,并且返回了一個與當前state成對的dispatch的方法。 咱們使用 useReducer 來編寫上面的求和例子。

useReducer((state,?acton)?=>?{
?return?state?+?action
},?0)
復制代碼

useReducer返回一個包含2個元素的數組,類似于useState hook。 第一個是當前狀態,第二個是dispatch方法,如下所示:

const?[sum,?dispatch]?=?useReducer((state,?action)?=>?{
?return?state?+?action
},?0)
復制代碼

注意,state可以是任何值,它不一定是一個對象,可以是一個數字,一個數組,或者其他任何類型。

盡管 useReducer 是擴展的 hook, 而 useState 是基本的 hook,但 useState 實際上執行的也是一個 useReducer。這意味著 useReducer 是更原生的,你能在任何使用 useState 的地方都替換成使用 useReducer。

import?React,?{?useReducer?}?from?'react';
function?Counter()?{
?//?First?render?will?create?the?state,?and?it?will
?//?persist?through?future?renders
?const?[sum,?dispatch]?=?useReducer((state,?action)?=>?{
?return?state?+?action;
?},?0);
?return?(
?<>
?{sum}
?<button?onClick={()?=>?dispatch(1)}>
?Add?1
?</button>
?</>
?);
}
復制代碼

點擊按鈕dispatch一個值為1的action,該action將被添加到當前狀態,然后組件使用新的狀態重新渲染。

這里故意展示了,派發action沒有遵循Redux的典型模式{type: "INCREMENT BY"、value: 1}或其他類似的東西。hook 的世界是一個新的世界:值得考慮的是,你是否發現舊的模式有價值并希望保留它們,或者你是否愿意更改它們。

一些更復雜的例子

再來看看更接近典型Redux reducer 的例子。創建一個組件來管理購物列表,這里看還會使用另外一個 hook:useRef。

首先,導入兩個 hook

import?React,?{?useReducer,?useRef?}?from?'react';
復制代碼

然后創建一個設置ref和reducer的組件。 ref保存對表單的引用,以便咱們可以提取其值。

function?ShoppingList()?{
?const?inputRef?=?useRef();
?const?[items,?dispatch]?=?useReducer((state,?action)?=>?{
?switch?(action.type)?{
?//?do?something?with?the?action
?}
?},?[]);
?return?(
?<>
?<form?onSubmit={handleSubmit}>
?<input?ref={inputRef}?/>
?</form>
?<ul>
?{items.map((item,?index)?=>?(
?<li?key={item.id}>
?{item.name}
?</li>
?))}
?</ul>
?</>
?);
}
復制代碼

請注意,在這種情況下,咱們的“state”是一個數組。 咱們通過useReducer第二個參數將它初始化為一個空數組,并從reducer函數返回一個數組。

useRef Hook

useRef hook為DOM節點創建持久引用。 調用useRef會創建一個空的節點。它返回的對象具有current屬性,因此在上面的示例中,咱們可以使用inputRef.current訪問輸入的DOM節點。 如果你熟悉React.createRef(),則其工作原理非常相似。

但是,useRef返回的對象不僅僅是一種保存DOM引用的方法。 它可以保存特定于此組件實例的任何值,并且它在渲染之間保持不變。

useRef可用于創建通用實例變量,就像使用具有this.whatever = value的React類組件一樣。 唯一的問題是,寫入它會被視為“副作用”,因此咱們無法在渲染過程中更改它,需要在useEffect hook 中才能修改。

回到useReducer示例

我們用表單來處理用戶的輸入,按回車提交表彰。 現在來編寫handleSubmit函數,該函數主要做的是將一個項添加到列表中,以及處理reducer中的 action。

function?ShoppingList()?{
?const?inputRef?=?useRef();
?const?[items,?dispatch]?=?useReducer((state,?action)?=>?{
?switch?(action.type)?{
?case?'add':
?return?[
?...state,
?{
?id:?state.length,
?name:?action.name
?}
?];
?default:
?return?state;
?}
?},?[]);
?function?handleSubmit(e)?{
?e.preventDefault();
?dispatch({
?type:?'add',
?name:?inputRef.current.value
?});
?inputRef.current.value?=?'';
?}
?return?(
?//?...?same?...
?);
}
復制代碼

在reducer函數中主要判斷兩種情況:一種用于action.type==='add'的情況,還有就是默認下的情況。

當action.type為 add 時,它返回一個包含所有舊元素的新數組,以及最后的新元素。

這里有一點需要注意的是,咱們使用數組的length作為一種自動遞增的 ID 方便演示,但是對于一個真正的應用程序來說這是不可靠,因為它可能導致重復的ID和bug。(最好使用uuid這樣的庫,或者讓服務器生成一個惟一的ID!)

當用戶在輸入框中按Enter鍵時會調用handleSubmit函數,因此咱們需要調用preventDefault以避免在發生這種情況時重新加載整頁。 然后dispatch派發一個 action。

刪除項

現在來看看如何從列表中刪除項的。

在項目中添加一個刪除<button>,點擊該按鈕派發 它將發送一個 action type === "remove"的操作,以及要刪除的項的索引。

然后咱們只需要在reducer中處理該action

function?ShoppingList()?{
?const?inputRef?=?useRef();
?const?[items,?dispatch]?=?useReducer((state,?action)?=>?{
?switch?(action.type)?{
?case?'add':
?//?...?same?as?before?...
?case?'remove':
?//?keep?every?item?except?the?one?we?want?to?remove
?return?state.filter((_,?index)?=>?index?!=?action.index);
?default:
?return?state;
?}
?},?[]);
?function?handleSubmit(e)?{?/*...*/?}
?return?(
?<>
?<form?onSubmit={handleSubmit}>
?<input?ref={inputRef}?/>
?</form>
?<ul>
?{items.map((item,?index)?=>?(
?<li?key={item.id}>
?{item.name}
?<button
?onClick={()?=>?dispatch({?type:?'remove',?index?})}
?>
?X
?</button>
?</li>
?))}
?</ul>
?</>
?);
}
復制代碼

練習:清空列表

試著添加一個功能:添加一個清空列表的按鈕。

在<ul>上方插入一個按鈕,并為其提供一個onClick prop,派發一個action ,type 為“clear”的動作,并在 reducer 方法執行清空列表的動作。

可以在前面 CodeSandbox的基礎上完成。

Redux 會死嗎

大部分人看到useReducer hook, React 現在已經內置了reducer ,它有Context傳遞數據,所以可能會想到 Redux 會不會因此就死了,以下是原作者給出的一些看法。

作者不認為useReducer會殺死Redux。React Hook 擴展了React在狀態管理方面的能力,所以會讓使用 Redux的情況減少。

Redux仍然比Context + useReducer的組合做得更多,它具有Redux DevTools 用于調試,可定制中間件、,以及整個相關庫生態系統,當然 Redu x在很多地方都被過度使用了,但它仍然具有強大的功能。

Redux提供了一個全局存儲,可以在其中集中保存應用程序數據。useReducer本地化到特定組件。但是,沒有什么可以阻止咱們使用useReducer和useContext構建自己的迷你redux 。如果你想這么做,而且符合你的需要,那就去做吧!

代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。

如何使用useReducer Hook


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新野县| 内江市| 上蔡县| 宁陵县| 安仁县| 从化市| 湛江市| 阿拉善盟| 科技| 肇庆市| 香港| 安宁市| 金乡县| 宜兴市| 庆城县| 拉萨市| 霍邱县| 华蓥市| 尉犁县| 万全县| 遂昌县| 夏津县| 武城县| 蕲春县| 茂名市| 芦溪县| 荥阳市| 新田县| 来安县| 延寿县| 宿迁市| 胶南市| 中阳县| 银川市| 开远市| 嘉鱼县| 建湖县| 两当县| 沾化县| 临泽县| 榆树市|