美文网首页
setState的理解和相关问题

setState的理解和相关问题

作者: 苍老师的眼泪 | 来源:发表于2022-07-19 17:14 被阅读0次

setState是异步的

import React from 'react'
import ReactDOM from 'react-dom/client'



class App extends React.Component {
    constructor(props) {
        super(props)
        this.state =  {
            count: 20,
            age: 26,
        }    
    }
    increase() {

        // setState是异步的
        // 即使这里有多次调用setState,并且修改了不同的state,但最终render只执行了一次

        this.setState({
            count: this.state.count+1,
            age: this.state.age+1,
        })

        this.setState({
            count: this.state.count+2
        })

        this.setState({
            count: this.state.count+3
        })

        this.setState({
            count: this.state.count+4
        })
    }
    render() {
        console.log('render 执行了')
        return (
            <div>
                <h2>{this.state.count}</h2>
                <h2>{this.state.age}</h2>
                <button onClick={() => this.increase()}><h2>click</h2></button>
            </div>
        )
    }
}


const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App></App>)

setState异步带来的问题

import React from 'react'
import ReactDOM from 'react-dom/client'



class App extends React.Component {
    constructor(props) {
        super(props)
        this.state =  {
            count: 20,
        }    
    }
    increase() {
        // 这里如果一秒钟只能快速点击两次使得increase被调用两次,
        // 但是最后count只增加了1,因为它第二次读取到count的时候依然为21,产生bug
        // 这里的setTimeout只是模拟setState的异步情况,真实情况中也是有可能出现这个问题的
        // https://react.docschina.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

        // let count = this.state.count
        // setTimeout(() => {
        //     this.setState({
        //         count: count+1,
        //     })
        // }, 1000);

        // 简单情况下的解决方法: 每次获取state里面的值
        setTimeout(() => {
            this.setState({
                count: this.state.count + 1,
            })
        }, 1000);


        // 官方的解决方法:
        // setTimeout(() => {

        //     this.setState((state, props) => ({
        //         count: state.count +  1
        //     }))

        // }, 1000);
    }
    render() {
        console.log('render 执行了')
        return (
            <div>
                <h2>{this.state.count}</h2>
                <h2>{this.state.age}</h2>
                <button onClick={() => this.increase()}><h2>click</h2></button>
            </div>
        )
    }
}


const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App></App>)

state hook 也会出现这种bug:

import React from 'react'
import ReactDOM from 'react-dom/client'



function App(props) {
    let [count, setCount] = React.useState(20)

    function increase() {
        // state hook 也会出现这种bug
        // setTimeout(() => {
        //     setCount(count + 1)
        // }, 1000);

        // 解决方法:给react传一个用于更新state的回调函数
        setTimeout(() => {
            // react 确保回调函数的参数是最新的
            setCount(preCount => {
                return preCount + 1
            })
        }, 1000);
    }

    return (
        <div>
            <h2>{count}</h2>
            <button onClick={() => increase()}>click</button>
        </div>
    )
}


const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App></App>)

相关文章

网友评论

      本文标题:setState的理解和相关问题

      本文链接:https://www.haomeiwen.com/subject/eqbsirtx.html