其实 博主之前是搞vue开发的,后来就转了react,现在全职搞react也有两个月了, 之前面试的时候碰见一个 有趣的问题,
面试官问 如何在react中实现同步的写法,我有点疑惑了,说实话刚转过来,对react并不是太熟悉 有的功能也没有完全摸透。

我就实话说说了,这个还真没有用过呢, 麻烦老哥稍微提点一下,那个面试官就说了,在某些原生js事件种,或者 setTimeout 和 setIntrval中可以获取到 最新的state状态 达到同步的效果。

这里 我们来尝试看下 效果哈

  1. 拿类式组件 来做例子了
componentDidMount() {
    this.setState({
      count: 1
    })
    console.log(this.state.count);
  }
  render() {
    const { count } = this.state;
    console.log('render', '===')
    return (
      <div>
        {count}
        <button>+1</button>
      </div>
    )

上面代码很容易理解 setState 是 异步延时执行的
所以顺序应该是
0
render =====
在这里插入图片描述
实际情况也确实 是我们猜想的那样
注意
1.1 还有一种情况 就是 如果 多个setState的话 那么 react内部会做处理 只会render一次
1.2 不要 setState 对象 和 函数的两种方法 混着用 比如

this.setState({count: 0})
this.setState((state) => ({count:  state.count + 1}))
this.setState({count: 0})
  1. 那我们怎么实现同步的执行的呢
    上面说了 就是在原生的事件绑定中 或者 定时器中
    来看个小例子
componentDidMount() {
    setTimeout(() => {
      this.setState({
        count: 1
      })
      console.log(this.state.count);
    }, 0)
  }
  render() {
    const { count } = this.state;
    console.log('render', '===')
    return (
      <div>
        {count}
        <button>+1</button>
      </div>
    )
  }

在这里插入图片描述
还有一种就是 使用 使用原生js的方式 来进行处理

  componentDidMount() {
    document.querySelector('#btn').addEventListener('click', () => {
      this.setState({count: 1});
      console.log(JSON.stringify(this.state.count))
    })
  }

也会达到上面的效果

在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。

其实 我们在 react自己封装的事件或者函数中 , 使用的setState() 都是 异步执行的,
比如 生命周期中,或者 onClick 或者 onChange什么的
但是原生的或者定时器中 不受react这个框架的掌控

虽然可以 实现同步 但是还是要避免 使用这种方式,我们知道这个东西,但不是一定要去使用它, 会带来一系列的 性能问题

好了 关注我 持续更新前端知识

Logo

前往低代码交流专区

更多推荐