setState的异步,同步以及合并

setState
<body>
    <div id="test"></div>
</body>
<!-- 核心库 -->
<script type="text/javascript" src="js/react.development.js"></script>
<!-- 基于React专门用于操作DOM的扩展库 -->
<script type="text/javascript" src="js/react-dom.development.js"></script>
<!-- babel解析JSX语法代码转换为js代码 -->
<script type="text/javascript" src="js/babel.min.js"></script>
<script type="text/babel">/*text/babel 就是让babel进行解析*/
    class A extends React.Component{
        state = {
            count:1
        }
        // 函数形式参数和对象形式参数修改 react相关的回调都是异步的 如果在紧随其后打印修改的值可能不会是修改后的
        // 要想获得需要使用setState的第二个参数  是个回调函数 这个回调函数是会等异步完成的
        // 函数形式参数  是依赖原本state中的值的是直接对其中的值进行更改
        test1 = () => {
            this.setState(state => ({count:state.count + 1}),()=>{
                console.log('callback test1',this.state.count)
            })
            console.log('commont test1',this.state.count)
        }
        // 对象形式参数  是不依赖的 有中间赋值给其他变量的过程  可以和state中原本的值关系不大
        test2 = () => {
            const count = this.state.count - 1
            this.setState({count},()=>{
                console.log('callback test2',this.state.count)
            })
            console.log('commont test2',this.state.count)
        }
        render(){
            console.log('A renduer')
            return(
                <div>
                    <h1>Addd:{this.state.count}</h1>
                    <button onClick={this.test1}>111111</button>
                    <button onClick={this.test2}>222222</button>
            )
        }
    }
    ReactDOM.render(<A/>,document.getElementById('test'))
</script>

在这里插入图片描述

react相关回调(异步)和其他回调(同步)

react相关回调,比如:react的监听事件,生命周期函数等

其他回调,比如:DOM的事件监听,定时器函数,Promise等

<body>

<div id="example"></div>

<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script type="text/javascript" src="./js/babel.min.js"></script>

<script type="text/babel">
  class StateTest extends React.Component {

    state = {
      count: 0,
    }

    /*
     react事件监听回调中, setState()是异步更新状态
     */
    update1 = () => {
      console.log('update1 setState()之前', this.state.count)
      this.setState(state => ({count: state.count + 1}))
      console.log('update1 setState()之后', this.state.count)
    }

    /*
     react生命周期勾子中, setState()是异步更新状态
     */
    componentDidMount () {
      console.log('componentDidMount setState()之前', this.state.count)
      this.setState(state => ({count: state.count + 1}))
      console.log('componentDidMount setState()之后', this.state.count)
    }

    /*
    定时器回调 / 原生事件监听回调 / promise回调 /...
     */
    update2 = () => {
      setTimeout(() => {
        console.log('setTimeout setState()之前', this.state.count)
        this.setState(state => ({count: state.count + 1}))
        console.log('setTimeout setState()之后', this.state.count)
      })
    }
    update3 = () => {
      const h2 = this.refs.count
      h2.onclick = () => {
        console.log('onclick setState()之前', this.state.count)
        this.setState(state => ({count: state.count + 1}))
        console.log('onclick setState()之后', this.state.count)
      }
    }
    update4 = () => {
      Promise.resolve().then(value => {
        console.log('Promise setState()之前', this.state.count)
        this.setState(state => ({count: state.count + 1}))
        console.log('Promise setState()之后', this.state.count)
      })
    }


    update5 = () => {
      console.log('onclick setState()之前', this.state.count)
      this.setState(state => ({count: state.count + 1}))
      console.log('onclick setState()之后', this.state.count)
      console.log('onclick setState()之前2', this.state.count)
      this.setState(state => ({count: state.count + 1}))
      console.log('onclick setState()之后2', this.state.count)

    }


    render() {
      const {count} = this.state
      console.log('render()', count)
      return (
        <div>
          <h2 ref='count'>{count}</h2>
          <button onClick={this.update1}>更新1</button> ---
          <button onClick={this.update2}>更新2</button> &nbsp;
          <button onClick={this.update3}>更新3</button> &nbsp;
          <button onClick={this.update4}>更新4</button> ---
          <button onClick={this.update5}>更新5</button> &nbsp;
         
        </div>
      )
    }
  }

  ReactDOM.render(<StateTest/>, document.getElementById('example')) // 渲染组件标签, 内部会调用组件标签对象的render()虚拟DOM

</script>
</body>

多次调用异步的setState,在合并前(在render渲染前,要进行合并,因为渲染只进行一次),对于函数形式的只会取决于结束最晚的那次更新,因为异步起始读取的都是state不会是其他异步处理完毕的内容,在结束时每个异步会重复覆盖之完成的异步的内容,也就是他会保存最新的状态

而对象形式参数 会进行多次的状态更新,但也是一次渲染

如果对象跟函数两个模式混用

  • 对象在前 会进行多次的状态更新,但也是一次渲染
  • 函数在前 直接合并
   update6 = () => {
      console.log('onclick setState()之前', this.state.count)
      this.setState({count: this.state.count + 1})
      console.log('onclick setState()之后', this.state.count)
      console.log('onclick setState()之前2', this.state.count)
      this.setState({count: this.state.count + 1})
      console.log('onclick setState()之后2', this.state.count)
    }
    update7 = () => {
      console.log('onclick setState()之前', this.state.count)
      this.setState({count: this.state.count + 1})
      console.log('onclick setState()之后', this.state.count)

      console.log('onclick setState()之前2', this.state.count)
      this.setState(state => ({count: state.count + 1}))
      console.log('onclick setState()之后2', this.state.count)
            }
    
    
    
     <button onClick={this.update6}>更新6</button> &nbsp;
     <button onClick={this.update7}>更新7</button> &nbsp;

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值