欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

快速總結(jié):

場(chǎng)景

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

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

代碼實(shí)現(xiàn)方面,內(nèi)部維護(hù)一個(gè) 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>
  );
}

正常使用這個(gè)組件時(shí)一切都是正常的。

問題出現(xiàn)

不過當(dāng)你需要在一個(gè) Select 組件中切換 type 時(shí),就會(huì)出現(xiàn)一個(gè)問題,切換過程中間會(huì)閃現(xiàn)過一個(gè) 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}>動(dòng)物</Radio>
          <Radio value={1}>水果</Radio>
        </Radio.Group>
        <MySelect type={type} value={value} onChange={handleChange} />
      </Flex>
    </div>
  );
}

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

尋找解決方案

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

useLayoutEffect

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

將 useEffect 全部改成 useLayoutEffect。

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

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

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

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

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

react 最佳實(shí)踐

prop 改變后 state 同步這個(gè)在 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ù)中直接更新組件時(shí),React 會(huì)丟棄返回的 JSX 并立即重新渲染。不過為了避免非常緩慢的級(jí)聯(lián)重試,React 只允許你在組件函數(shù)中更新同一組件的狀態(tài)。

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

總結(jié)

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

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

例如以下方式處理 innerOptions:

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

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

相關(guān)文章

  • react 不用插件實(shí)現(xiàn)數(shù)字滾動(dòng)的效果示例

    react 不用插件實(shí)現(xiàn)數(shù)字滾動(dòng)的效果示例

    這篇文章主要介紹了react 不用插件實(shí)現(xiàn)數(shù)字滾動(dòng)的效果示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • create-react-app使用antd按需加載的樣式無效問題的解決

    create-react-app使用antd按需加載的樣式無效問題的解決

    這篇文章主要介紹了create-react-app使用antd按需加載的樣式無效問題的解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • 在react中使用mockjs的方法你知道嗎

    在react中使用mockjs的方法你知道嗎

    這篇文章主要為大家詳細(xì)介紹了在react中使用mockjs的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • React Native中Mobx的使用方法詳解

    React Native中Mobx的使用方法詳解

    這篇文章主要給大家介紹了關(guān)于React Native中Mobx的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • 詳解如何構(gòu)建自己的react hooks

    詳解如何構(gòu)建自己的react hooks

    我們組的前端妹子在組內(nèi)分享時(shí)談到了 react 的鉤子,趁此機(jī)會(huì)我也對(duì)我所理解的內(nèi)容進(jìn)行下總結(jié),方便更多的同學(xué)了解。在 React 的 v16.8.0 版本里添加了 hooks 的這種新的 API,我們非常有必要了解下他的使用方法,并能夠結(jié)合我們的業(yè)務(wù)編寫幾個(gè)自定義的 hooks。
    2021-05-05
  • 詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟

    詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟

    本篇文章主要介紹了詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • react.js 翻頁插件實(shí)例代碼

    react.js 翻頁插件實(shí)例代碼

    這篇文章主要介紹了react.js 翻頁插件實(shí)例代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • Iconfont不能上傳如何維護(hù)Icon

    Iconfont不能上傳如何維護(hù)Icon

    這篇文章主要為大家介紹了在Iconfont還是不能上傳,要如何維護(hù)你的Icon,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • React 對(duì)接流式接口的具體使用

    React 對(duì)接流式接口的具體使用

    React應(yīng)用中對(duì)接流式接口通常涉及到處理實(shí)時(shí)數(shù)據(jù)傳輸,本文就來介紹一下React 對(duì)接流式接口的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • 優(yōu)雅的在React項(xiàng)目中使用Redux的方法

    優(yōu)雅的在React項(xiàng)目中使用Redux的方法

    這篇文章主要介紹了優(yōu)雅的在React項(xiàng)目中使用Redux的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11

最新評(píng)論