動態

詳情 返回 返回

React setState、useState同步?異步? - 動態 詳情

React setState、useState到底是同步的,還是異步的?

setState語法

用法1:

this.setState({
  //  數據更新
})

用法2:

this.setState((state, props) => {
  // 當前組件的state
  // 父級的state
}, () => {
  // 數據更新之後
})

useState語法

用法1:

const [num, setNum] = useState(0);
...
setNum(1);

用法2:

const [num, setNum] = useState(0);
...
setNum(() => {
  // 數據操作
});

setState是同步還是異步?

看一下下面的代碼:

import React from 'react';
import { Button } from 'antd-mobile';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  onButtonClick() {
    setTimeout(() => {
      this.setState({
        count: 1
      })
      console.log('count00000', this.state.count);
    })

    console.log('count111111', this.state.count);
    setTimeout(() => {
      console.log('count222222', this.state.count);
    })
  }

  render() {
    return (
      <div>
        <Button onClick={this.onButtonClick.bind(this)}>點擊</Button>
        <div>
          這個數字就是啊哈哈哈:{this.state.count}
        </div>
      </div>
    )
  }
}

打印結果:
image.png

setState 只在合成事件和鈎子函數中是“異步”的,在原生事件和 setTimeout 中都是同步的。

合成事件:就是react 在組件中的onClick等都是屬於它自定義的合成事件。
原生事件:比如通過addeventListener添加的,dom中的原生事件。

原生事件舉例:

state = {
    count:0
};
componentDidMount() {
    document.body.addEventListener('click', this.changeVal, false);
}
changeVal = () => {
    this.setState({
      number: 1
    })
    console.log(this.state.count)
}

useState是同步還是異步?

看一下下面代碼:

import React, { useState } from 'react';
import { Button } from 'antd-mobile';
import './index.scss';

const HospitalInfo = () => {
  const [count, setCount] = useState(0);

  const onButtonClick = () => {
    setTimeout(() => {
      setCount(1);
      console.log('count0000', count)
    })

    console.log('count111', count)
    setTimeout(() => {
      console.log('count222', count)
    })
  }

  return (
    <div className="page-hospital-container">
      <Button onClick={onButtonClick}>點擊</Button>
      <div>這個數字就是:{count}</div>
    </div>
  );
};

export default HospitalInfo;

image.png
然後,我們發現都沒有獲取到最新值,説明useState是異步的!

那如何獲取最新值呢?

const [count, setCount] = useState(0);
  const countRef = useRef(count);
  countRef.current = count;

  const onButtonClick = () => {
    setTimeout(() => {
      setCount(1);
      console.log('count0000', count)
    })

    console.log('count--Ref11', countRef)


    console.log('count111', count)
    setTimeout(() => {
      console.log('count222', count)
      console.log('count--Ref22', countRef)
    })
  }

看一下結果:
image.png

我們發現在Hooks最近中如果想要獲取到最新值,需要在異步+Ref的方式才能獲取到!

個人見解,有什麼不對的地方,歡迎大神評論區留言😄

user avatar tianmiaogongzuoshi_5ca47d59bef41 頭像 toopoo 頭像 cyzf 頭像 front_yue 頭像 jingdongkeji 頭像 dirackeeko 頭像 zourongle 頭像 linx 頭像 hard_heart_603dd717240e2 頭像 shuirong1997 頭像 jiavan 頭像 yqyx36 頭像
點贊 104 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.