最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于React狀態(tài)管理的三個規(guī)則總結(jié)

 更新時間:2021年07月31日 10:35:38   作者:前端先鋒  
隨著 JavaScript 單頁應(yīng)用開發(fā)日趨復(fù)雜,JavaScript 需要管理比任何時候都要多的 state (狀態(tài)),這篇文章主要給大家介紹了關(guān)于React狀態(tài)管理的三個規(guī)則,需要的朋友可以參考下

前言

React 組件內(nèi)部的狀態(tài)是在渲染過程之間保持不變的封裝數(shù)據(jù)。useState() 是 React hook,負(fù)責(zé)管理功能組件內(nèi)部的狀態(tài)。

我喜歡 useState() ,它確實使?fàn)顟B(tài)處理變得非常容易。但是我經(jīng)常遇到類似的問題:

  • 我應(yīng)該將組件的狀態(tài)劃分為小狀態(tài),還是保持復(fù)合狀態(tài)?
  • 如果狀態(tài)管理變得復(fù)雜,我應(yīng)該從組件中提取它嗎?該怎么做?
  • 如果 useState() 的用法是如此簡單,那么什么時候需要 useReducer()?

本文介紹了 3 條簡單的規(guī)則,可以回答上述問題,并幫助你設(shè)計組件的狀態(tài)。

No.1 一個關(guān)注點

有效狀態(tài)管理的第一個規(guī)則是:

使?fàn)顟B(tài)變量負(fù)責(zé)一個問題。

使?fàn)顟B(tài)變量負(fù)責(zé)一個問題使其符合單一責(zé)任原則。

讓我們來看一個復(fù)合狀態(tài)的示例,即一種包含多個狀態(tài)值的狀態(tài)。

const [state, setState] = useState({
    on: true,
    count: 0
});

state.on    // => true
state.count // => 0

狀態(tài)由一個普通的 JavaScript 對象組成,該對象具有 on 和 count 屬性。

第一個屬性 state.on 包含一個布爾值,表示開關(guān)。同樣,``state.count` 包含一個表示計數(shù)器的數(shù)字,例如,用戶單擊按鈕的次數(shù)。

然后,假設(shè)你要將計數(shù)器加1:

// Updating compound state
setUser({
    ...state,
    count: state.count + 1
});

你必須將整個狀態(tài)放在一起,才能僅更新 count。這是為了簡單地增加一個計數(shù)器而調(diào)用的一個大結(jié)構(gòu):這都是因為狀態(tài)變量負(fù)責(zé)兩個方面:開關(guān)和計數(shù)器。

解決方案是將復(fù)合狀態(tài)分為兩個原子狀態(tài) on 和 count:

const [on, setOnOff] = useState(true);
const [count, setCount] = useState(0);

狀態(tài)變量 on 僅負(fù)責(zé)存儲開關(guān)狀態(tài)。同樣,count 變量僅負(fù)責(zé)計數(shù)器。

現(xiàn)在,讓我們嘗試更新計數(shù)器:

setCount(count + 1);
// or using a callback
setCount(count => count + 1);

count 狀態(tài)僅負(fù)責(zé)計數(shù),很容易推斷,也很容易更新和讀取。

不必?fù)?dān)心調(diào)用多個 useState() 為每個關(guān)注點創(chuàng)建狀態(tài)變量。

但是請注意,如果你使用過多的 useState() 變量,則你的組件很有可能就違反了“單一職責(zé)原則”。只需將此類組件拆分為較小的組件即可。

No.2 提取復(fù)雜的狀態(tài)邏輯

將復(fù)雜的狀態(tài)邏輯提取到自定義 hook 中。

在組件內(nèi)保留復(fù)雜的狀態(tài)操作是否有意義?

答案來自基本面(通常會發(fā)生這種情況)。

創(chuàng)建 React hook 是為了將組件與復(fù)雜狀態(tài)管理和副作用隔離開。因此,由于組件只應(yīng)關(guān)注要渲染的元素和要附加的某些事件偵聽器,所以應(yīng)該把復(fù)雜的狀態(tài)邏輯提取到自定義 hook 中。

考慮一個管理產(chǎn)品列表的組件。用戶可以添加新的產(chǎn)品名稱。約束是產(chǎn)品名稱必須是唯一的。

第一次嘗試是將產(chǎn)品名稱列表的設(shè)置程序直接保留在組件內(nèi)部:

function ProductsList() {
    const [names, setNames] = useState([]);  
    const [newName, setNewName] = useState('');

    const map = name => <div>{name}</div>;

    const handleChange = event => setNewName(event.target.value);
    const handleAdd = () => {    
        const s = new Set([...names, newName]);    
        setNames([...s]);  };
    return (
        <div className="products">
            {names.map(map)}
            <input type="text" onChange={handleChange} />
            <button onClick={handleAdd}>Add</button>
        </div>
    );
}

names 狀態(tài)變量保存產(chǎn)品名稱。單擊 Add 按鈕時,將調(diào)用 addNewProduct() 事件處理程序。

在 addNewProduct() 內(nèi)部,用 Set 對象來保持產(chǎn)品名稱唯一。組件是否應(yīng)該關(guān)注這個實現(xiàn)細(xì)節(jié)?不需要。

最好將復(fù)雜的狀態(tài)設(shè)置器邏輯隔離到一個自定義 hook 中。開始做吧。

新的自定義鉤子 useUnique() 可使每個項目保持唯一性:

// useUnique.js
export function useUnique(initial) {
    const [items, setItems] = useState(initial);
    const add = newItem => {
        const uniqueItems = [...new Set([...items, newItem])];
        setItems(uniqueItems);
    };
    return [items, add];
};

將自定義狀態(tài)管理提取到一個 hook 中后,ProductsList 組件將變得更加輕巧:

import { useUnique } from './useUnique';

function ProductsList() {
  const [names, add] = useUnique([]);  const [newName, setNewName] = useState('');

  const map = name => <div>{name}</div>;

  const handleChange = event => setNewName(e.target.value);
  const handleAdd = () => add(newName);
  return (
    <div className="products">
      {names.map(map)}
      <input type="text" onChange={handleChange} />
      <button onClick={handleAdd}>Add</button>
    </div>
  );
}

const [names, addName] = useUnique([]) 啟用自定義 hook。該組件不再被復(fù)雜的狀態(tài)管理所困擾。

如果你想在列表中添加新名稱,則只需調(diào)用 add('New Product Name') 即可。

最重要的是,將復(fù)雜的狀態(tài)管理提取到自定義 hooks 中的好處是:

  • 該組件不再包含狀態(tài)管理的詳細(xì)信息
  • 自定義 hook 可以重復(fù)使用
  • 自定義 hook 可輕松進(jìn)行隔離測試

No.3 提取多個狀態(tài)操作

將多個狀態(tài)操作提取到化簡器中。

繼續(xù)用 ProductsList 的例子,讓我們引入“delete”操作,該操作將從列表中刪除產(chǎn)品名稱。

現(xiàn)在,你必須為 2 個操作編碼:添加和刪除產(chǎn)品。處理這些操作,就可以創(chuàng)建一個簡化器并使組件擺脫狀態(tài)管理邏輯。

同樣,此方法符合 hook 的思路:從組件中提取復(fù)雜的狀態(tài)管理。

以下是添加和刪除產(chǎn)品的 reducer 的一種實現(xiàn):

function uniqueReducer(state, action) {
    switch (action.type) {
        case 'add':
            return [...new Set([...state, action.name])];
        case 'delete':
            return state.filter(name => name === action.name);
        default:
            throw new Error();
    }
}

然后,可以通過調(diào)用 React 的 useReducer()  hook 在產(chǎn)品列表中使用 uniqueReducer():

function ProductsList() {
    const [names, dispatch] = useReducer(uniqueReducer, []);
    const [newName, setNewName] = useState('');

    const handleChange = event => setNewName(event.target.value);

    const handleAdd = () => dispatch({ type: 'add', name: newName });
    const map = name => {
        const delete = () => dispatch({ type: 'delete', name });    
        return (
            <div>
                {name}
                <button onClick={delete}>Delete</button>
            </div>
        );
    }

    return (
        <div className="products">
            {names.map(map)}
            <input type="text" onChange={handleChange} />
            <button onClick={handleAdd}>Add</button>
        </div>
    );
}

const [names, dispatch] = useReducer(uniqueReducer, []) 啟用 uniqueReducer。names 是保存產(chǎn)品名稱的狀態(tài)變量,而 dispatch 是使用操作對象調(diào)用的函數(shù)。

當(dāng)單擊 Add 按鈕時,處理程序?qū)⒄{(diào)用 dispatch({ type: 'add', name: newName })。調(diào)度一個 add 動作使 reducer uniqueReducer 向狀態(tài)添加一個新的產(chǎn)品名稱。

以同樣的方式,當(dāng)單擊 Delete 按鈕時,處理程序?qū)⒄{(diào)用 dispatch({ type: 'delete', name })。remove 操作將產(chǎn)品名稱從名稱狀態(tài)中刪除。

有趣的是,reducer 是命令模式的特例。

總結(jié)

狀態(tài)變量應(yīng)只關(guān)注一個點。

如果狀態(tài)具有復(fù)雜的更新邏輯,則將該邏輯從組件提取到自定義 hook 中。

同樣,如果狀態(tài)需要多個操作,請用 reducer 合并這些操作。

無論你使用什么規(guī)則,狀態(tài)都應(yīng)該盡可能地簡單和分離。組件不應(yīng)被狀態(tài)更新的細(xì)節(jié)所困擾:它們應(yīng)該是自定義 hook 或化簡器的一部分。

這 3 個簡單的規(guī)則能夠使你的狀態(tài)邏輯易于理解、維護(hù)和測試。

到此這篇關(guān)于React狀態(tài)管理的三個規(guī)則的文章就介紹到這了,更多相關(guān)React狀態(tài)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Jenkins部署React項目的方法步驟

    使用Jenkins部署React項目的方法步驟

    這篇文章主要介紹了使用Jenkins部署React項目的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • React實現(xiàn)點擊刪除列表中對應(yīng)項

    React實現(xiàn)點擊刪除列表中對應(yīng)項

    本文主要介紹了React 點擊刪除列表中對應(yīng)項的方法。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • React useMemo與useCallabck有什么區(qū)別

    React useMemo與useCallabck有什么區(qū)別

    useCallback和useMemo是一樣的東西,只是入?yún)⒂兴煌?,useCallback緩存的是回調(diào)函數(shù),如果依賴項沒有更新,就會使用緩存的回調(diào)函數(shù);useMemo緩存的是回調(diào)函數(shù)的return,如果依賴項沒有更新,就會使用緩存的return
    2022-12-12
  • 詳解react-router4 異步加載路由兩種方法

    詳解react-router4 異步加載路由兩種方法

    本篇文章主要介紹了詳解react-router4 異步加載路由兩種方法 ,具有一定的參考價值,有興趣的可以了解一下
    2017-09-09
  • react-native組件中NavigatorIOS和ListView結(jié)合使用的方法

    react-native組件中NavigatorIOS和ListView結(jié)合使用的方法

    這篇文章主要給大家介紹了關(guān)于react-native組件中NavigatorIOS和ListView結(jié)合使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-09-09
  • 詳解React中共享組件邏輯的三種方式

    詳解React中共享組件邏輯的三種方式

    這篇文章主要介紹了詳解React中共享組件邏輯的三種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 教你應(yīng)用?SOLID?原則整理?React?代碼之單一原則

    教你應(yīng)用?SOLID?原則整理?React?代碼之單一原則

    這篇文章主要介紹了如何應(yīng)用?SOLID?原則整理?React?代碼之單一原則,今天,我們將從一個糟糕的代碼示例開始,應(yīng)用 SOLID 的第一個原則,看看它如何幫助我們編寫小巧、漂亮、干凈的并明確責(zé)任的 React 組件,需要的朋友可以參考下
    2022-07-07
  • react-native 實現(xiàn)漸變色背景過程

    react-native 實現(xiàn)漸變色背景過程

    這篇文章主要介紹了react-native 實現(xiàn)漸變色背景過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 解決React報錯React?Hook?useEffect?has?a?missing?dependency

    解決React報錯React?Hook?useEffect?has?a?missing?dependency

    這篇文章主要為大家介紹了解決React報錯React?Hook?useEffect?has?a?missing?dependency,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • react-redux的connect與React.forwardRef結(jié)合ref失效的解決

    react-redux的connect與React.forwardRef結(jié)合ref失效的解決

    這篇文章主要介紹了react-redux的connect與React.forwardRef結(jié)合ref失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論

长乐市| 抚远县| 菏泽市| 陵水| 南昌市| 鹤壁市| 呼伦贝尔市| 左云县| 甘泉县| 弋阳县| 芮城县| 桃园县| 金沙县| 甘南县| 荆门市| 甘孜县| 钟祥市| 固原市| 北川| 松溪县| 洪雅县| 松江区| 云南省| 巴林右旗| 蓝田县| 庆元县| 龙岩市| 兴文县| 罗田县| 林周县| 山丹县| 马边| 永平县| 崇阳县| 沂源县| 静乐县| 九龙城区| 新巴尔虎右旗| 河源市| 林芝县| 开江县|