React中的setState/useState怎么使用

2023-05-12,,

这篇文章主要介绍“React中的setState/useState怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React中的setState/useState怎么使用”文章能帮助大家解决问题。

    一、React如何使用setState/useState的最新的值

    一般是可以正常的把最新的值,传递给所需要的函数中的,但是有些情况,需要使用最新数据的函数,不可改动,甚至所需要使用的地方并不是一个函数,那我们如何获取setState/useState的最新的值呢?

    A.使用setState的最新的值

    1、setState方法可以接收两个参数,第一个参数为一个对象,第二个参数为一个函数,即更新成功后执行的回调函数。我们可以在回调函数中获取更新后的值。

    import React, { Component } from 'react'
    export default class DemoClassComp extends Component {
      constructor(props) {
        super(props)
        this.state = {
          number: 1,
        }
      }
      inControl = ()=>{
        this.setState({number: 1}, () => {
          console.log('%c ???? DemoClassComp -> inControl -> this.state.number ', 'font-size:16px;background-color:#f31440;color:white;', this.state.number)
        })
      }
      render() {
        return (
          <div>
            <button onClick={this.inControl} >点我</button>
          </div>
        )
      }
    }

    2、使用setTimeout

    B.使用useState的最新的值

    1、使用另一个Hook,useRef;

    function DemoFuncComp() {
      const [qimingFlag, setQimingFlag] = useState(false);
      const qimingFlagRef = useRef(false);
      const handleLine = () => {
        deleteQimingFieldsData(data, qimingFlagRef?.current); //* 删除启明相关字段的数据
      }
      const initData = useCallback(async () => {
        await commonQuery(basicInfoHeader, { contractId });
        const qimingFlagNow = basicInfoHeader.current?.get('qimingFlag');
        setQimingFlag(qimingFlagNow); //* 用于出发重新渲染
        qimingFlagRef.current = qimingFlagNow;
        handleLine(); //* 要求 先setQimingFlag
      }, [contractId])
      /**生命周期 */
      useEffect(() => {
        initData();
      }, [contractId]);
      return (
        <>
          <Form dataSet={basicInfoHeader} disabled={true} columns={4}>
            <Lov name="receiverObj" />
        </Form>
        </>
      )
    }

    2、使用setTimeout

    二、React中setState/useState执行的同步异步问题

    只要代码进入了 react调度流程,那就是异步的。

    只要代码没有进入 react调度流程,那就是同步的。

    setTimeout、setInterval、async中await的后续部分,Promise.then(),以及直接在 DOM 上绑定原生事件等。这些都不会走 React调度流程,在这种情况下调用 setState ,那这次 setState 就是同步的。 否则就是异步的。

    连续执行两个 useState

    function DemoFuncComp() {
      const [a, setA] = useState(0);
      const [b, setB] = useState(0);
      console.log('render')
      function outControl() {
        Promise.resolve().then(() => {
          setA((a) => a + 1);
          setB((b) => b + 1);
        })
      }
      function inControl() {
        setA((a) => a + 1);
        setB((b) => b + 1);
      }
      return (
        <>
          <button onClick={outControl} >{a}-{b} 【不受react调度】</button>
          <button onClick={inControl} >{a}-{b} 【react调度】</button>
        </>
      )
    }
    //! 当点击【不受react调度】按钮时,render 了两次
    //! 当点击【react调度】按钮时,只重新 render 了一次

    连续执行两次同一个 useState

    function DemoFuncComp() {
      const [a, setA] = useState(1)
      console.log('a', a)
      function outControl() {
        Promise.resolve().then(() => {
          setA((a) => a + 1)
          setA((a) => a + 1)
        })
      }
      function inControl() {
        setA((a) => a + 1)
        setA((a) => a + 1)
      }
      return (
        <>
          <button onClick={outControl} >{a} 【不受react调度】</button>
          <button onClick={inControl} >{a} 【react调度】</button>
        </>
      )
    }
    //! 当点击【不受react调度】按钮时,两次 setA 各自 render 一次,分别打印 2,3
    //! 当点击【react调度】按钮时,两次 setA 都执行,但合并 render 了一次,打印 3

    连续执行两个 setState

    class DemoClassComp extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          a: 1,
          b: 'b',
        }
      }
      outControl = () => {
        Promise.resolve().then(() => {
          this.setState({...this.state, a: 'aa'})
          this.setState({...this.state, b: 'bb'})
        })
      }
      inControl = () => {
        this.setState({...this.state, a: 'aa'})
        this.setState({...this.state, b: 'bb'})
      }
      render() {
        console.log('render')
        return (
          <>
            <button onClick={this.outControl} >【不受react调度】</button>
            <button onClick={this.inControl} >【react调度】</button>
          </>
        )
      }
    }
    //! 当点击【不受react调度】按钮时,render 了两次
    //! 当点击【react调度】按钮时,只重新 render 了一次

    连续执行两次同一个 setState

    class DemoClassComp extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          a: 1,
        }
      }
      outControl = () => {
        Promise.resolve().then(() => {
          this.setState({a: this.state.a + 1})
          this.setState({a: this.state.a + 1})
        })
      }
      inControl = () => {
        this.setState({a: this.state.a + 1})
        this.setState({a: this.state.a + 1})
      }
      render() {
        console.log('a', this.state.a)
        return (
          <>
            <button onClick={this.outControl} >【不受react调度】</button>
            <button onClick={this.inControl} >【react调度】</button>
          </>
        )
      }
    }
    //! 当点击【不受react调度】按钮时,两次 setState 各自 render 一次,分别打印 2,3
    //! 当点击【react调度】按钮时,两次 setState 合并,只执行了最后一次,打印 2

    关于“React中的setState/useState怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注本站行业资讯频道,小编每天都会为大家更新不同的知识点。

    《React中的setState/useState怎么使用.doc》

    下载本文的Word格式文档,以方便收藏与打印。