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

React?state結(jié)構(gòu)設(shè)計(jì)原則示例詳解

 更新時(shí)間:2023年06月01日 08:36:12   作者:小烏龜快跑  
這篇文章主要為大家介紹了React?state結(jié)構(gòu)設(shè)計(jì)原則示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

React State 結(jié)構(gòu)設(shè)計(jì)

React 中組件 state 狀態(tài)管理是組件設(shè)計(jì)中的難點(diǎn)之一,如何設(shè)計(jì)state的結(jié)構(gòu)。遵循以下原則可以保障state更新不出現(xiàn)邏輯上的錯(cuò)誤,也可以避免不必要的 state 維護(hù):

相關(guān)的狀態(tài)組合成一個(gè)group

當(dāng)每次觸發(fā)更新的時(shí)候需要更新兩個(gè)state 則這兩個(gè)state可以嘗試合并成一個(gè)state【從單個(gè)值類(lèi)型,變成object 或者 Array 等類(lèi)型】。

import { useState } from 'react';
function ComA() {
  // bad case 
  const [x, setX] = useState<number>(0);
  const [y, setY] = useState<number>(0);
  // good case
  const [position, setPosition] = useState({ x: 0, y: 0 });
  return (
    <div>
      <div style={{
          position: 'absolute',
          backgroundColor: 'red',
          borderRadius: '50%',
          transform: `translate(${x}px, ${y}px)`,
          left: -10,
          top: -10,
          width: 20,
          height: 20,
        }} />
    </div>
    );
}

避免出現(xiàn)競(jìng)態(tài)的state

也就是說(shuō)兩個(gè)或多個(gè) state 存在競(jìng)態(tài),同一時(shí)刻有且僅有一個(gè)是真值。如果存在這種問(wèn)題,則需要考慮避免當(dāng)前這種state的結(jié)構(gòu), 使用不同的值去區(qū)分沖突的 state,這樣就把多個(gè)沖突的state 合并成1個(gè)state,區(qū)別在于value的變化以及其代表的意義。

import { useState } from 'react';
// bad  case
function ComA() {
  // 表示編輯狀態(tài)
  const [isWritting, setIsWritting] = useState(true);
  // 表示是否保存
  const [isSave, setIsSave] = useState(fasle);
  // 其他狀態(tài)
  const [isComplete, setIsComplete] = useState(false);
  return (
    //...
  );
}
// 這中間 isWriting 和 isSave 是沖突的。也就是說(shuō)兩個(gè)state存在競(jìng)態(tài),有且僅有一個(gè)是真值。
// combine mutilate state ingroup 
function ComB() {
  const [status, setStatus] = useState<'writing' | 'save' | 'complete'>('writing');
  return (
    // ...
  );
}

避免多余的state

如果一個(gè) state 可以通過(guò)其他 state 的計(jì)算得出【.length, 取反異或等】,那么這個(gè) state 就是不需要存在的。

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');
  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
    setFullName(e.target.value + ' ' + lastName);
  }
  function handleLastNameChange(e) {
    setLastName(e.target.value);
    setFullName(firstName + ' ' + e.target.value);
  }
  return (
    <>
      <h2>Let's check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
// fullname  完全可以由 firstName 和 lastName 拼接出來(lái),使用單獨(dú)的 state 來(lái)保存計(jì)算結(jié)果是多余的。

避免重復(fù)的狀態(tài)

如果state存在重復(fù)相同的數(shù)據(jù)時(shí),這部分重復(fù)的數(shù)據(jù)很難保持同步更新。【一般是針對(duì)數(shù)組項(xiàng)的處理,data 保存在一個(gè)state 中,然后又使用一個(gè)state保存選中或者編輯某項(xiàng)。這時(shí)候data中的數(shù)據(jù)更新,current 可能會(huì)被緩存到舊值】。需要避免這種重復(fù)。解決辦法【避免保存重復(fù)的內(nèi)容,而是保存找到指定數(shù)據(jù)的id或者索引】。

import { useState } from 'react';
const defaultData = [
    { title: 'Tom', id: 0 },
    { title: 'Sam', id: 1 },
    { title: 'Dodo', id: 2 },
    { title: 'Piker', id: 3 },
];
function ComA() {
    const [data, setData] = useState(defaultData);
    const [current, setCurrent] = useState(data[0]);
    function handleClick(item) {
      setCurrent(item);
    }
    function handleInput(id, value) {
      const newData = data.map((item)=>{
        if (id === item.id) {
          return { ...item, title: value };
        }
        return item;
      })
    }
  return (
    <>
      <ul>
        {
          data.map((item) => {
            return (
              <li key={item.id}>
                <input value={item.title} onChange= {({target})=>{ handleInput(item.id, target.value); }}/>
                <button onClick={()=>{ handleClick(item) }}>選中</button>
              </li>
            );
          })
        }
      </ul>
      <p>當(dāng)前選中:{current.title}</p>
     </>
  );
}
// 問(wèn)題: 當(dāng)點(diǎn)擊 “選中” 按鈕后, current 保存了當(dāng)前 item 的一個(gè)引用。接著編輯當(dāng)前項(xiàng)的title,發(fā)現(xiàn)并不會(huì)同步到<p>中展示。

解決方法1

細(xì)心檢查代碼能看出來(lái),通過(guò) handleInput 執(zhí)行時(shí),返回了新的對(duì)象更新 data 中的 item。只要稍微修改一下handleInput的代碼,同時(shí)更新current即可。

function handleInput(id, value) {
      const newData = data.map((item)=>{
        if (id === item.id) {
          // return { ...item, title: value };
          const newItem = { ...item, title: value };
          setCurrent(newItem);
          return newItem;
        }
        return item;
      })
    }

但是這種方式不能一勞永逸,其他函數(shù)中再修改其他屬性數(shù)據(jù),還得增加同樣的邏輯。

解決方法2

保存 item 的 id 不要保存重復(fù)的數(shù)據(jù)內(nèi)容。

import { useState } from 'react';
const defaultData = [
    { title: 'Tom', id: 0 },
    { title: 'Sam', id: 1 },
    { title: 'Dodo', id: 2 },
    { title: 'Piker', id: 3 },
];
function ComA() {
    const [data, setData] = useState(defaultData);
    // 修改
    const [currentId, setCurrentId] = useState(0);
    const currentItem = data.find(({id}) => id === currentId);
    function handleClick({id}) {
      setCurrentId(id);
    }
    function handleInput(id, value) {
      const newData = data.map((item)=>{
        if (id === item.id) {
          return { ...item, title: value };
        }
        return item;
      })
    }
  return (
    <>
      <ul>
        {
          data.map((item) => {
            return (
              <li key={item.id}>
                <input value={item.title} onChange= {({target})=>{ handleInput(item.id, target.value); }}/>
                <button onClick={()=>{ handleClick(item) }}>選中</button>
              </li>
            );
          })
        }
      </ul>
      <p>當(dāng)前選中:{current.title}</p>
     </>
  );
}

一勞永逸解決問(wèn)題,保存id。更新的時(shí)候組件會(huì)自動(dòng)獲取對(duì)應(yīng)的數(shù)據(jù)項(xiàng)

避免出現(xiàn)過(guò)深的嵌套state

深度嵌套的state不便于更新,更新時(shí),需要一層一層的解構(gòu),重組成新的嵌套對(duì)象。如果可以嘗試使用平鋪的方式組織state結(jié)構(gòu)。react 進(jìn)行state更新時(shí),引用類(lèi)型數(shù)據(jù)需要使用新的引用結(jié)構(gòu)進(jìn)行更新【解構(gòu)復(fù)制,修改對(duì)應(yīng)value】,如果嵌套層級(jí)過(guò)多,更新時(shí)解構(gòu)層級(jí)越復(fù)雜,容易出問(wèn)題。

以這些原則作為 state 結(jié)構(gòu)設(shè)計(jì)方法論,逐步實(shí)現(xiàn)性感&合理的 React 組件!

更多關(guān)于React state 結(jié)構(gòu)設(shè)計(jì)原則的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React 實(shí)現(xiàn)表單組件的示例代碼

    React 實(shí)現(xiàn)表單組件的示例代碼

    本文主要介紹了React 實(shí)現(xiàn)表單組件的示例代碼,支持包括輸入狀態(tài)管理,表單驗(yàn)證,錯(cuò)誤信息展示,表單提交,動(dòng)態(tài)表單元素等功能,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • react中使用signal的項(xiàng)目實(shí)踐

    react中使用signal的項(xiàng)目實(shí)踐

    本文主要介紹了react中使用signal的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • react-router?重新加回跳轉(zhuǎn)攔截功能詳解

    react-router?重新加回跳轉(zhuǎn)攔截功能詳解

    這篇文章主要為大家介紹了react-router?重新加回跳轉(zhuǎn)攔截功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • React中實(shí)現(xiàn)keepalive組件緩存效果的方法詳解

    React中實(shí)現(xiàn)keepalive組件緩存效果的方法詳解

    由于react官方并沒(méi)有提供緩存組件相關(guān)的api(類(lèi)似vue中的keepalive),在某些場(chǎng)景,會(huì)使得頁(yè)面交互性變的很差。所以本文為大家介紹了React中實(shí)現(xiàn)keepalive組件緩存效果的方法,希望對(duì)大家有所幫助
    2023-01-01
  • React懶加載實(shí)現(xiàn)原理深入分析

    React懶加載實(shí)現(xiàn)原理深入分析

    懶加載意思是不會(huì)預(yù)加載,而是需要使用某段代碼,某個(gè)組件或者某張圖片時(shí),才加載他們(延遲加載),這篇文章主要介紹了React懶加載實(shí)現(xiàn)原理
    2022-11-11
  • React實(shí)現(xiàn)基于Antd密碼強(qiáng)度校驗(yàn)組件示例詳解

    React實(shí)現(xiàn)基于Antd密碼強(qiáng)度校驗(yàn)組件示例詳解

    這篇文章主要為大家介紹了React實(shí)現(xiàn)基于Antd密碼強(qiáng)度校驗(yàn)組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 基于webpack4.X從零搭建React腳手架的方法步驟

    基于webpack4.X從零搭建React腳手架的方法步驟

    這篇文章主要介紹了基于webpack4.X從零搭建React腳手架的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • React高頻useEffect導(dǎo)致頁(yè)面崩潰的有效解決方案

    React高頻useEffect導(dǎo)致頁(yè)面崩潰的有效解決方案

    如果你在 React 中遇到過(guò)頁(yè)面卡死、高頻請(qǐng)求、useEffect 無(wú)限觸發(fā),這篇文章會(huì)幫你一次搞懂根因,并提供可直接復(fù)制的最佳解決方案,需要的朋友可以參考下
    2025-11-11
  • React調(diào)度系統(tǒng)Scheduler工作原理詳解

    React調(diào)度系統(tǒng)Scheduler工作原理詳解

    這篇文章主要為大家介紹了React調(diào)度系統(tǒng)Scheduler工作原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • React + Threejs + Swiper 實(shí)現(xiàn)全景圖效果的完整代碼

    React + Threejs + Swiper 實(shí)現(xiàn)全景圖效果的完整代碼

    全景圖效果非常漂亮給人帶來(lái)極好的用戶(hù)體驗(yàn)效果,那么基于前端開(kāi)發(fā)如何實(shí)現(xiàn)這種效果呢,下面小編給大家?guī)?lái)了React + Threejs + Swiper 實(shí)現(xiàn)全景圖效果,感興趣的朋友一起看看吧
    2021-06-06

最新評(píng)論

富平县| 太白县| 乌恰县| 乡城县| 常山县| 健康| 东平县| 揭阳市| 开鲁县| 梁平县| 吉木萨尔县| 淮北市| 安阳市| 会理县| 绩溪县| 嘉荫县| 黔南| 封丘县| 临潭县| 麟游县| 宕昌县| 德江县| 来凤县| 孝感市| 凉山| 修水县| 琼海市| 苍梧县| 紫阳县| 南木林县| 屏东市| 龙山县| 锡林浩特市| 三穗县| 房产| 上蔡县| 政和县| 庐江县| 邢台市| 双峰县| 广元市|