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

詳解React如何優(yōu)雅地根據(jù)prop更新state值

 更新時間:2023年11月14日 08:22:58   作者:曉得迷路了  
這篇文章主要為大家詳細介紹了React如何優(yōu)雅地實現(xiàn)根據(jù)prop更新state值,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴可以了解下

快速總結(jié):

場景

開發(fā) React 組件中,有時會碰到同步狀態(tài)的問題,就是當(dāng) prop 變化時調(diào)整組件的 state 值。

比如以下這個場景:一個下拉組件 Select 內(nèi)置了兩組選項內(nèi)容,支持通過 type 來選擇,同時也支持傳入 options 參數(shù)自定義選項內(nèi)容。

代碼實現(xiàn)方面,內(nèi)部維護一個 innerOptions,外部參數(shù) typeoptions 通過 useEffect 來同步,相關(guān)代碼如下:

import React, { useState, useEffect } from "react";
import { Flex, Space, Select } from "antd";

function MySelect({ value, onChange, type, options }) {
  const optionsList = [[
    { value: "dog", label: "小狗" },
    { value: "cat", label: "小貓" },
  ], [
    { value: "banana", label: "香蕉" },
    { value: "apple", label: "蘋果" },
  ]]
  const [innerOptions, setInnerOptions] = useState(options || optionsList[type] || [])

  useEffect(() => {
    if (type !== undefined) {
      setInnerOptions(optionsList[type])
    }
  }, [type]);

  useEffect(() => {
    if (options !== undefined) {
      setInnerOptions(options)
    }
  }, [options])

  return (
    <Space direction="vertical">
      {`你選擇了:${innerOptions.find((item) => item.value === value)?.label}`}
      <Select
        style={{ width: 120 }}
        value={value}
        onChange={onChange}
        options={innerOptions}
      />
    </Space>
  );
}

正常使用這個組件時一切都是正常的。

問題出現(xiàn)

不過當(dāng)你需要在一個 Select 組件中切換 type 時,就會出現(xiàn)一個問題,切換過程中間會閃現(xiàn)過一個 undefined 。

import React, { useState } from "react;
import { Flex, Space } from "antd";
import MySelect from "./MySelect";

function App() {
  const [value, setValue] = useState("dog");
  const [type, setType] = useState(0);

  const handleChange = (newVal) => {
    setValue(newVal);
  };

  const handleChangeType = (e) => {
    setType(e.target.value);
    setValue(e.target.value === 0 ? 'dog' : 'banana')
  }

  return (
    <div className="App">
      <Flex gap="middle" vertical>
        <Radio.Group onChange={handleChangeType} value={type}>
          <Radio value={0}>動物</Radio>
          <Radio value={1}>水果</Radio>
        </Radio.Group>
        <MySelect type={type} value={value} onChange={handleChange} />
      </Flex>
    </div>
  );
}

問題的原因是切換選項時,value 值是直接更新的,而 innerOptionsuseEffect 中更新的,也就是中間會出現(xiàn)一次 value 為新值,而 innerOptions 為舊值的渲染。

尋找解決方案

既然找到了原因,就開始想辦法處理這個問題。

useLayoutEffect

第一時間想到了用 useLayoutEffect 能否解決, useLayoutEffect 在 react 文檔中說明是在將內(nèi)容真正渲染到屏幕前調(diào)用,并且會阻塞瀏覽器重繪。

將 useEffect 全部改成 useLayoutEffect。

useLayoutEffect(() => {
    if (type !== undefined) {
      setInnerOptions(optionsList[type])
    }
}, [type]);

useLayoutEffect(() => {
    if (options !== undefined) {
      setInnerOptions(options)
    }
}, [options])

可以看到不會出現(xiàn) undefined 的情況了。

useLayoutEffect 會降低性能。在可能的情況下,最好使用 useEffect。

不過官方文檔有提到 useLayoutEffect 會降低性能,再看看是否有更好的方案。

react 最佳實踐

prop 改變后 state 同步這個在 react 文檔中有編碼建議。

官方推薦不要使用 useEffect,在函數(shù)中直接調(diào)整 state 值。

const [innerOptions, setInnerOptions] = useState(options || optionsList[type] || [])
const [prevType, setPrevType] = useState(type);
const [prevOptions, setPrevOptions] = useState(options);

if (prevType !== type) {
    setPrevType(type);
    setInnerOptions(optionsList[type])
}

if (prevOptions !== options) {
    setPrevOptions(type);
    setInnerOptions(options)
}

上面的代碼比起使用 useEffect 的代碼可能并不常見。

當(dāng)你在組件渲染函數(shù)中直接更新組件時,React 會丟棄返回的 JSX 并立即重新渲染。不過為了避免非常緩慢的級聯(lián)重試,React 只允許你在組件函數(shù)中更新同一組件的狀態(tài)。

也就是說 value 為新值,而 innerOptions 為舊值的渲染被丟棄了,所以不會出現(xiàn) undefined 的情況,問題也得到了解決。

總結(jié)

正常情況下,我們使用 useEffect 來將 prop 更新到 state 是沒問題的。不過在有界面渲染的情況下,可能會有 bug 出現(xiàn),這時需要使用 useLayoutEffect 或者直接在組件渲染函數(shù)中更新 state 值。

其實根據(jù) prop 更新 state 在非必要的情況下盡量不要出現(xiàn),優(yōu)先考慮在渲染函數(shù)中直接根據(jù) prop 計算狀態(tài)或者通過 key 值重新渲染整個組件

例如以下方式處理 innerOptions:

// 直接根據(jù) prop 計算狀態(tài)
const innerOptions = optionsList[type] || options || []

以上就是詳解React如何優(yōu)雅地根據(jù)prop更新state值的詳細內(nèi)容,更多關(guān)于React更新state值的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React 全面解析excel文件

    React 全面解析excel文件

    這篇文章主要介紹了React 全面解析excel文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • TypeScript在React項目中的使用實踐總結(jié)

    TypeScript在React項目中的使用實踐總結(jié)

    這篇文章主要介紹了TypeScript在React項目中的使用總結(jié),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • react的嚴(yán)格模式和解決react useEffect執(zhí)行兩次問題

    react的嚴(yán)格模式和解決react useEffect執(zhí)行兩次問題

    文章總結(jié):本文詳細探討了React中useEffect執(zhí)行兩次的問題,主要歸因于React的嚴(yán)格模式,嚴(yán)格模式在開發(fā)模式下會故意重復(fù)調(diào)用一些生命周期方法,以幫助開發(fā)者發(fā)現(xiàn)潛在的問題,包括不安全的生命周期、過時的ref API、廢棄的findDOMNode方法、意外的副作用等
    2025-01-01
  • 用react實現(xiàn)一個簡單的scrollView組件

    用react實現(xiàn)一個簡單的scrollView組件

    這篇文章主要給大家介紹一下如何用 react 實現(xiàn)一個簡單的 scrollView組件,文中有詳細的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-07-07
  • React教程之Props驗證的具體用法(Props Validation)

    React教程之Props驗證的具體用法(Props Validation)

    這篇文章主要介紹了React教程之Props驗證的具體用法(Props Validation),非常具有實用價值,需要的朋友可以參考下
    2017-09-09
  • 淺談React 中的淺比較是如何工作的

    淺談React 中的淺比較是如何工作的

    React 中淺比較的概念無處不在,它在不同的流程中起著關(guān)鍵的作用,本文主要介紹了React 中的淺比較是如何工作的,具有一定的參考價值,感興趣的可以了解一下
    2022-04-04
  • React實現(xiàn)輪播圖效果

    React實現(xiàn)輪播圖效果

    這篇文章主要為大家詳細介紹了React實現(xiàn)輪播圖效果,使用react-slick組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • React倒計時功能實現(xiàn)代碼——解耦通用

    React倒計時功能實現(xiàn)代碼——解耦通用

    這篇文章主要介紹了React倒計時功能實現(xiàn)——解耦通用,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • React實現(xiàn)阿里云OSS上傳文件的示例

    React實現(xiàn)阿里云OSS上傳文件的示例

    這篇文章主要介紹了React實現(xiàn)阿里云OSS上傳文件的示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • React+Vite中利用Fetch將CSV數(shù)據(jù)轉(zhuǎn)成JSON字符串

    React+Vite中利用Fetch將CSV數(shù)據(jù)轉(zhuǎn)成JSON字符串

    在一些小型項目中,前端可能需要直接處理 CSV 文件數(shù)據(jù),將其轉(zhuǎn)換為 JSON 字符串后再進行邏輯操作和展示,本文將會介紹兩種方法,需要的朋友可以參考下
    2025-12-12

最新評論

富顺县| 深州市| 东港市| 新乐市| 乐业县| 儋州市| 鄂伦春自治旗| 鹤峰县| 石渠县| 大竹县| 连州市| 大关县| 衡阳市| 龙里县| 东安县| 临猗县| 昌平区| 邓州市| 荆门市| 奉贤区| 馆陶县| 曲水县| 淳安县| 民勤县| 义马市| 西贡区| 德化县| 淳安县| 石渠县| 江城| 龙门县| 宝兴县| 高雄县| 杭锦旗| 普陀区| 韶关市| 隆德县| 阜平县| 龙里县| 聂荣县| 石阡县|