国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

02react 函數(shù)組件useState的異步問題

這篇具有很好參考價(jià)值的文章主要介紹了02react 函數(shù)組件useState的異步問題。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

react 函數(shù)組件

常見的鉤子函數(shù):useState、useEffect

useState的異步

useState作為最常見的一個(gè)hook,在使用中總是會(huì)出現(xiàn)各種坑,最明顯的就是 useState 更新異步的問題。

  • 問題描述:把接口返回的數(shù)據(jù),使用 useState 儲(chǔ)存起來,但是當(dāng)后面去改變這個(gè)數(shù)據(jù)的時(shí)候,每次拿到的都是上次的數(shù)據(jù),無法實(shí)時(shí)更新。或者我們在函數(shù)內(nèi)部使用 setState ,然后立即打印 state,打印的結(jié)果還是第一次的state 的值。
  • 原因:useState 返回的更新對象的方法是異步的,要在下次重繪才能獲取新值,不要試圖在更改狀態(tài)之后立即獲取狀態(tài)。
  • 控制臺(tái)報(bào)錯(cuò):
    react usestate set值異步,react,react.js,前端,javascript
  • 代碼,函數(shù)組件:
import React, { useState, useEffect } from 'react';
import styles from './index.less';
export default function index({ content = {} }) {
  const [data, setData] = useState([]);
  useEffect(() => {
    if (content !== null) {
      const myModityData = content.title.split('***');
      setData(myModityData);
    }
  }, [content.title]);
  return (
    <div className={styles.home_box}>
      <div className={styles.title}>{data[0]}</div>
      <div className={styles.titleBottom}>{data[1]}</div>
      <p className={styles.des}>{content.des}</p>
    </div>
  );
}

原因總結(jié):

這是因?yàn)镽eact里事件分為合成事件和原生事件,合成事件和鉤子函數(shù)都是異步的,原生事件是同步的。因?yàn)?strong>useState是異步事件,所以會(huì)出現(xiàn)不能及時(shí)獲取到最新值的情況。
useState 返回的更新狀態(tài)方法是異步的,要在下次重繪才能獲取新值。不要試圖在更改狀態(tài)之后立馬獲取狀態(tài)。
注意:useEffect的第二個(gè)參數(shù),我表明監(jiān)聽content.title但還是不行,因?yàn)樵赗eact的函數(shù)組件中使用useState進(jìn)行數(shù)據(jù)存儲(chǔ),導(dǎo)致數(shù)據(jù)異步,不能及時(shí)獲取當(dāng)前最新的數(shù)據(jù)。

解決辦法思路:

  • 辦法一:先使用useRef進(jìn)行存儲(chǔ)數(shù)據(jù),再使用useEffect監(jiān)聽數(shù)據(jù)變化,并進(jìn)行更新。
    在之后需要使用 info 數(shù)據(jù)的地方只需要獲取 infoRef.current 即可獲取最新的 info 數(shù)據(jù)內(nèi)容。
import React, { useState, useEffect, useRef } from 'react';

const Index = () => {
	const [info, setInfo] = useState()
	const infoRef = useRef()
	useEffect(() => {
		infoRef.current = info
	}, [info])
}

  • 辦法二:使用回調(diào)函數(shù)更改數(shù)據(jù)
  • useState 使用的兩種方式
    我們知道,useState中的 [ ] 是一個(gè)解構(gòu)運(yùn)算,第一個(gè)是設(shè)置的值,第二個(gè)是用來改變 state 的方法。
    一般情況下,我們使用第一種方式即可,但在某些特殊情況下,第一種方式獲取到的值不是最新設(shè)置的。
const [data, setData] = useState(1)
setData(data + 1)
const [data, setData] = useState(0)
setData((prev) => prev + 1); // prev 是data 改變之前的值,return 返回的值會(huì)作為新狀態(tài)覆蓋data

原文鏈接:React hooks中 useState踩坑——異步問題

實(shí)際解決辦法:

辦法一:頁面能渲染出來,但控制臺(tái)報(bào)錯(cuò),監(jiān)聽會(huì)一直存在,很耗能

控制臺(tái)報(bào)錯(cuò):
react usestate set值異步,react,react.js,前端,javascript
中文解釋:警告:超過了最大更新深度。當(dāng)組件在useEffect內(nèi)部調(diào)用setState時(shí),可能會(huì)發(fā)生這種情況,但useEffect要么沒有依賴關(guān)系數(shù)組,要么依賴關(guān)系在每次渲染時(shí)都會(huì)發(fā)生變化。

代碼:
react usestate set值異步,react,react.js,前端,javascript

完整代碼:

const UAVEdge = (props) => {
  const { UAVEdgeModel, dispatch } = props;
  const { productLists, typeId, page } = UAVEdgeModel;
  const [data, setData] = useState(productLists);
  const myRef = useRef();
  useEffect(() => {
    myRef.current = data;
    const myDeleteData = myRef.current.slice(0, 1);
    setData(myDeleteData);
  }, [data]);
  useEffect(() => {
    dispatch({
      type: 'UAVEdgeModel/getProductList',
    });
  }, []);
  return (
    <>
      <Banner content={uavDate} />
      <Content content={data} />
      <Content02 content={productLists} />
      {/* <Swiper /> */}
    </>
  );
};
export default connect(({ UAVEdgeModel }) => ({
  UAVEdgeModel,
}))(UAVEdge);

辦法二:useState(使用回調(diào)函數(shù))

控制臺(tái)報(bào)錯(cuò):
react usestate set值異步,react,react.js,前端,javascript
中文解釋:
未捕獲錯(cuò)誤:重新渲染過多。React限制渲染次數(shù),以防止無限循環(huán)。
代碼:
react usestate set值異步,react,react.js,前端,javascript

完整代碼:

import React, { useState, useEffect } from 'react';
import styles from './index.less';
export default function index({ content = [] }) {
  const [data, setData] = useState(content);
  setData((prev) => {
    const myDeleteData = prev.slice(1, 5);
    return myDeleteData
  })
  return (
    <div className={styles.home_box}>
      <div className={styles.home_container}>
        {data.map((item) => {
          return (
            <div className={styles.edge_box} key={item.id}>
              <div className={styles.boxContainer}>
                <img src={item.img} alt="一張圖" />
                <div className={styles.title}>{item.title}</div>
                <p className={styles.des}>{item.des}</p>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

辦法三:辦法一的改進(jìn)

代碼:
react usestate set值異步,react,react.js,前端,javascript

完整代碼:

import React, { useState, useEffect, useRef } from 'react';
import styles from './index.less';
export default function index({ content = [] }) {
  const [data, setData] = useState(content);
  const myRef = useRef();
  useEffect(() => {
    const myDeleteData = data.slice(1, 5);
    myRef.current = myDeleteData;
  }, [data]);
  return (
    <div className={styles.home_box}>
      <div className={styles.home_container}>
        {myRef.current?.map((item) => {
          return (
            <div className={styles.edge_box} key={item.id}>
              <div className={styles.boxContainer}>
                <img src={item.img} alt="一張圖" />
                <div className={styles.title}>{item.title}</div>
                <p className={styles.des}>{item.des}</p>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

辦法四:組件傳參的時(shí)候,傳數(shù)據(jù)

思路:組件傳參的時(shí)候,傳數(shù)據(jù)
控制臺(tái)報(bào)錯(cuò):
react usestate set值異步,react,react.js,前端,javascript
中文解釋:
需要獨(dú)一無二的key??墒俏颐髅饕呀?jīng)給了,為什么?
接口返回的數(shù)據(jù):
react usestate set值異步,react,react.js,前端,javascript
函數(shù)組件傳參,代碼:
react usestate set值異步,react,react.js,前端,javascript

函數(shù)組件傳參,完整代碼:

const UAVEdge = (props) => {
  const { UAVEdgeModel, dispatch } = props;
  const { productLists, typeId, page } = UAVEdgeModel;
  useEffect(() => {
    dispatch({
      type: 'UAVEdgeModel/getProductList',
    });
  }, []);
  return (
    <>
      <Banner content={uavDate} />
      <Content content={[productLists[0] || {}]} />
      <Content02 content={productLists} />
      {/* <Swiper /> */}
    </>
  );
};
export default connect(({ UAVEdgeModel }) => ({
  UAVEdgeModel,
}))(UAVEdge);

辦法五:辦法四的加強(qiáng)版

思路:把數(shù)據(jù)處理干凈傳過去,使用useRef()處理數(shù)據(jù)
代碼:
react usestate set值異步,react,react.js,前端,javascript

完整代碼:

const GroundEdge = (props) => {
  const { GroundEdgeModel, dispatch } = props;
  const { productLists, typeId, page } = GroundEdgeModel;
  const [data, setData] = useState(productLists);
  const myRef = useRef()
  useEffect(() => {
    const myDeleteData = data.slice(0,1);    
    myRef.current = myDeleteData
  }, [data]);
  useEffect(() => {
    dispatch({
      type: 'GroundEdgeModel/getProductList',
    });
  }, []);
  return (
    <>
      <Banner content={groDate} />
      <Content content={myRef.current} />
      <Content02 content={productLists} />
      {/* <Swiper /> */}
    </>
  );
};
export default connect(({ GroundEdgeModel }) => ({
  GroundEdgeModel,
}))(GroundEdge);

辦法六:辦法五的加強(qiáng)版

期望后端接口數(shù)據(jù):
react usestate set值異步,react,react.js,前端,javascript

實(shí)際后端接口數(shù)據(jù):
react usestate set值異步,react,react.js,前端,javascript

代碼:
react usestate set值異步,react,react.js,前端,javascript

完整代碼:

const OnboardEdge = (props) => {
  const { OnboardEdgeModel, dispatch } = props;
  const { productLists, typeId, page } = OnboardEdgeModel;
  const [info, setInfo] = useState(productLists);
  let infoRef = useRef();
  useEffect(() => {
    if (productLists !== null) {
      const myModityData = info.map((item) => {
        return {
          ...item,
          title: item.title.split('***'),
        };
      });
      infoRef.current = myModityData[0];
    }
  }, [info]);

  useEffect(() => {
    dispatch({
      type: 'OnboardEdgeModel/getProductList',
    });
  }, []);

  return (
    <div className={styles.home_box}>
      <Banner content={onbDate} />
      {/* <PageTitleThreeC content={productLists[0] || {}} /> */}
      <PageTitleThreeC content={infoRef.current} />
      <Content01 content={productLists[0]} />
      <Content02 content={productLists} />
      {/* <Swiper /> */}
    </div>
  );
};
export default connect(({ OnboardEdgeModel }) => ({
  OnboardEdgeModel,
}))(OnboardEdge);

推薦使用:辦法三useRef()

終極簡單:不解決異步問題

之前解決了那么多,但useState在項(xiàng)目實(shí)際中依然沒有解決。
終極簡單思路:處理“干凈的”數(shù)據(jù)傳給組件,再傳遞的時(shí)候進(jìn)行一個(gè)數(shù)組對象的截取react適用,vue沒有實(shí)踐過。
處理前:
react usestate set值異步,react,react.js,前端,javascript
處理后:
react usestate set值異步,react,react.js,前端,javascript
字符串轉(zhuǎn)數(shù)組:
期待把后端的數(shù)據(jù)title字段進(jìn)行一個(gè)split()截取
react usestate set值異步,react,react.js,前端,javascript

import React, { useState, useEffect, useRef } from 'react';
import styles from './index.less';
export default function index({ content = {} }) {
  let arr = [];
  if (content.title) {
    let title = content.title;
    arr = title.split('***');
  }
  return (
    <div className={styles.home_box}>
      <div className={styles.title}>{arr[0]}</div>
      <div className={styles.titleBottom}>{arr[1]}</div>
      <p className={styles.des}>{content.des}</p>
    </div>
  );
}

總結(jié):

大道求簡。在寫的過程中,一點(diǎn)一點(diǎn)完善,發(fā)現(xiàn)到了最后,有更加簡單的方法,根本不用走那一套。
你要問我有沒有意義,仁者見仁。文章來源地址http://www.zghlxwxcb.cn/news/detail-769733.html

到了這里,關(guān)于02react 函數(shù)組件useState的異步問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • React -- useState使用方法

    userState 是一個(gè)React Hook (函數(shù))。它允許我們向組件添加一個(gè)狀態(tài)變量,從而控制影響組件的渲染結(jié)果 1. useState是一個(gè)函數(shù),返回值是一個(gè)數(shù)組 2. 數(shù)組中第一個(gè)參數(shù)是狀態(tài)變量,第二個(gè)參數(shù)是set開頭的函數(shù)名,用于修改變量 3. useState的參數(shù)作為count的初始值 4.使用舉例

    2024年02月19日
    瀏覽(22)
  • [react] useState的一些小細(xì)節(jié)

    [react] useState的一些小細(xì)節(jié)

    因?yàn)閟etState修改是異步的,加上會(huì)觸發(fā)函數(shù)重新渲染, 如果代碼長這樣 ?一秒再修改,然后重新觸發(fā)setTImeout, 然后再觸發(fā),重復(fù)觸發(fā)循環(huán) 如果這樣呢 還是會(huì),因?yàn)槟銏?zhí)行又會(huì)重新渲染? 為什么修改多次還是跟不上呢? 因?yàn)槭钱惒叫薷?,所以會(huì)出現(xiàn)問題,怎么辦?用傳函數(shù)的形式解決 C

    2024年04月13日
    瀏覽(26)
  • React源碼解析18(6)------ 實(shí)現(xiàn)useState

    React源碼解析18(6)------ 實(shí)現(xiàn)useState

    在上一篇文章中,我們已經(jīng)實(shí)現(xiàn)了函數(shù)組件。同時(shí)可以正常通過render進(jìn)行渲染。 而通過之前的文章,beginWork和completeWork也已經(jīng)有了基本的架子?,F(xiàn)在我們可以去實(shí)現(xiàn)useState了。 實(shí)現(xiàn)之前,我們要先修改一下我們的index.js文件: 由于我們這一篇并不會(huì)實(shí)現(xiàn)React的事件機(jī)制,所以

    2024年02月13日
    瀏覽(30)
  • react中的useState和useImmer的用法

    react中的useState和useImmer的用法

    react中文官網(wǎng)教程 在函數(shù)式組件中,可以使用 useState 這個(gè) Hook 來定義和管理組件的狀態(tài)。 useState 接受一個(gè)初始狀態(tài)作為參數(shù),并返回一個(gè)包含 state 和更新 state 的方法的數(shù)組。 下面是一個(gè)例子,展示了如何在函數(shù)式組件中定義自己的 state: 在上面的例子中,我們使用 useStat

    2024年02月07日
    瀏覽(21)
  • React Hooks的useState、useRef使用

    React Hooks 是 React 16.8 版本引入的新特性,它允許你在不編寫 class 的情況下使用 state 和其他 React 特性。其中, useState ?和? useRef ?是兩個(gè)常用的 Hooks。 1. useState useState ?是一個(gè)允許你在函數(shù)組件中添加 state 的 Hook。 使用說明: useState ?返回一個(gè)狀態(tài)變量和一個(gè)設(shè)置該變量的函

    2024年02月02日
    瀏覽(22)
  • 解決useState 異步回調(diào)useGetState自定義hooks獲取不到最新值

    1、直接傳入新值 setState(options); 2、傳入回調(diào)函數(shù) setState(callBack); 通常情況下 setState 直接使用上述第一種方式傳參即可,但在一些特殊情況下第一種方式會(huì)出現(xiàn)異常; 例如希望在異步回調(diào)或閉包中獲取最新狀態(tài)并設(shè)置狀態(tài),此時(shí)第一種方式獲取的狀態(tài)不是實(shí)時(shí)的,React 官方文

    2024年02月06日
    瀏覽(21)
  • react中useState、setState、usemeno、meno區(qū)別

    useState和setState是異步 useState : useState 是React函數(shù)組件中的鉤子,用于聲明狀態(tài)變量。 通過 useState ,你可以在函數(shù)組件中添加狀態(tài),而無需創(chuàng)建類組件。 useState 返回一個(gè)數(shù)組,其中包含當(dāng)前狀態(tài)和一個(gè)更新狀態(tài)的函數(shù) setState : setState 是類組件中用于更新狀態(tài)的方法。 在類

    2024年02月22日
    瀏覽(22)
  • react18中,useState 和 useEffect有什么區(qū)別

    useState 目的:useState用于在函數(shù)組件中添加狀態(tài)。之前,只有類組件才能有自己的狀態(tài),但useState鉤子使得函數(shù)組件也能夠利用React的狀態(tài)特性。 使用場景:當(dāng)你需要在組件中存儲(chǔ)、讀取或更新一些數(shù)據(jù)時(shí)使用。例如,控制輸入框的內(nèi)容、切換按鈕的狀態(tài)等。 工作原理:useS

    2024年02月19日
    瀏覽(29)
  • react中useState的值沒有改變,而是舊的數(shù)值

    react中useState的值沒有改變,而是舊的數(shù)值

    想實(shí)現(xiàn)點(diǎn)擊按鈕就改變數(shù)據(jù)的效果,但是在控制臺(tái)的打印結(jié)果,總是上一次的修改情況,并不是最新的修改后的數(shù)據(jù) 代碼: 在 React 中, useState 是一個(gè)異步更新狀態(tài)的 Hook,因此在調(diào)用 setAName 更新狀態(tài)后, sonAName 并不會(huì)立即改變,而是會(huì)在下一次渲染時(shí)才會(huì)更新。 因此,在

    2024年04月26日
    瀏覽(21)
  • react useState useEffect useMemo實(shí)際業(yè)務(wù)場景中的使用

    react useState useEffect useMemo實(shí)際業(yè)務(wù)場景中的使用

    下面的代碼實(shí)現(xiàn)了上面圖片的功能

    2024年02月16日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包