1. How to use the latest value of setState/useState
Generally, the latest value can be passed to the required function normally. However, in some cases, functions that require the latest data cannot be changed, and even the required use is not a function. So how do we get the latest value of setState/useState?
A. Use the latest value of setState
1. The setState method can receive two parameters, the first parameter is an object, and the second parameter is a function, that is, the callback function executed after the update is successful. We can get the updated value in the callback function.
import React, { Component } from 'react' export default class DemoClassComp extends Component { constructor(props) { super(props) = { number: 1, } } inControl = ()=>{ ({number: 1}, () => { ('%c 📯 DemoClassComp -> inControl -> ', 'font-size:16px;background-color:#f31440;color:white;', ) }) } render() { return ( <div> <button onClick={} >Click me</button> </div> ) } }
2. Use setTimeout
B. Use the latest value of useState
1. Use another Hook, useRef;
function DemoFuncComp() { const [qimingFlag, setQimingFlag] = useState(false); const qimingFlagRef = useRef(false); const handleLine = () => { deleteQimingFieldsData(data, qimingFlagRef?.current); //* Delete data of Qiming-related fields } const initData = useCallback(async() => { await commonQuery(basicInfoHeader, { contractId }); const qimingFlagNow = ?.get('qimingFlag'); setQimingFlag(qimingFlagNow); //* for starting and re-rendering = qimingFlagNow; handleLine(); //* Requirement SetQimingFlag first }, [contractId]) /**life cycle */ useEffect(() => { initData(); }, [contractId]); return ( <> <Form dataSet={basicInfoHeader} disabled={true} columns={4}> <Lov name="receiverObj" /> </Form> </> ) }
2. Use setTimeout
2. Synchronous asynchronous problem of setState/useState execution in React
As long as the code enters the react scheduling process, it is asynchronous.
As long as the code does not enter the react scheduling process, it is synchronized.
setTimeout, setInterval, subsequent parts of await in async, (), and binding native events directly on the DOM, etc. None of these will go through the React scheduling process. In this case, setState is called, and this time setState is synchronized. Otherwise it is asynchronous.
Execute two useState in succession
function DemoFuncComp() { const [a, setA] = useState(0); const [b, setB] = useState(0); ('render') function outControl() { ().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} 【Not acceptedreactScheduling】</button> <button onClick={inControl} >{a}-{b} 【reactScheduling】</button> </> ) } //! When the [Not react scheduled] button was clicked, rendered twice//! When the [react schedule] button is clicked, it is only rendered once again
Execute the same useState twice in a row
function DemoFuncComp() { const [a, setA] = useState(1) ('a', a) function outControl() { ().then(() => { setA((a) => a + 1) setA((a) => a + 1) }) } function inControl() { setA((a) => a + 1) setA((a) => a + 1) } return ( <> <button onClick={outControl} >{a} 【Not acceptedreactScheduling】</button> <button onClick={inControl} >{a} 【reactScheduling】</button> </> ) } //! When clicking the [Not react scheduled] button, setA renders each time twice, and prints 2 and 3 respectively//! When the [react schedule] button is clicked, setA is executed twice, but the render is merged once, and 3 is printed
Execute two setState in succession
class DemoClassComp extends { constructor(props) { super(props) = { a: 1, b: 'b', } } outControl = () => { ().then(() => { ({..., a: 'aa'}) ({..., b: 'bb'}) }) } inControl = () => { ({..., a: 'aa'}) ({..., b: 'bb'}) } render() { ('render') return ( <> <button onClick={} >【Not acceptedreactScheduling】</button> <button onClick={} >【reactScheduling】</button> </> ) } } //! When the [Not react scheduled] button was clicked, rendered twice//! When the [react schedule] button is clicked, it is only rendered once again
Execute the same setState twice in a row
class DemoClassComp extends { constructor(props) { super(props) = { a: 1, } } outControl = () => { ().then(() => { ({a: + 1}) ({a: + 1}) }) } inControl = () => { ({a: + 1}) ({a: + 1}) } render() { ('a', ) return ( <> <button onClick={} >【Not acceptedreactScheduling】</button> <button onClick={} >【reactScheduling】</button> </> ) } } //! When clicking the [Not react scheduled] button, setState renders each time twice, and prints 2 and 3 respectively//! When the [react schedule] button is clicked, the setState merges twice, and only the last time is executed, and 2 is printed
Summarize
In normal react scheduling process:
- Both setState and useState are executed asynchronously
- Execute setState and useState multiple times, batchUpdate will be performed once, and render will be re-rendered once.
- The difference is that if you execute multiple times, setState will merge state, and useState will recalculate each time you run it.
When the react scheduling process is no longer in
- setState and useState are executed synchronously (update the state immediately, trigger the render, and then continue execution)
- Execute setState and useState multiple times. Each time the setState and useState are executed, the render will be called once.
This is the article about the detailed introduction to the use of setState/useState in React. For more related React setState/useState content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!