美文网首页
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