react setState同步操作

前言,我不是牛x的前端,但是这篇博客的知识,是从牛x的前端那儿偷师学来的!

牛 x 的前端是这么写:setState( 这里放一个函数 )
因为:
你以为的 state,其实不是现在新的 state 而是旧的 state
不太能理解我的意思?那往下看吧!
正常这么写

这是一个 +1 的 demo

class App extends React.Component {
  constructor() {
    super()
    this.state = { n: 0 }
  }
  add() {
    this.setState({ n: this.state.n + 1 })
  }
  render() {
    return (
      
n: {this.state.n}
) } }

牛x的前端这么写

还是一个 +1 的 demo,注意 add(){}

class App extends React.Component {
  constructor() {
    super()
    this.state = { n: 0 }
  }
  add() {
    this.setState(state => {
      return { n: state.n + 1 }
    })
  }
  render() {
    return (
      
n: {this.state.n}
) } }

对比
写法一: add() { this.setState({ n: this.state.n + 1 }) }
写法二: add() { this.setState(state => { return { n: state.n + 1 } }) }
那么,这两个写法是有什么区别呢?为什么 state() 里写一个函数就是牛x前端的写法了呢?
为什么不推荐写法一?
大部分时候,我们觉得,这个写法没有问题,因为点了 +1 按钮,一样可以正常加 1 啊!
但是!你在 加1 的时候,在代码下一行把 n 的值 log 出来看看,你会发现有问题 (具体什么问题,动动小手试一试)
add() { this.setState({ n: this.state.n + 1 }) }
console.log(this.state.n)
// UI 显示是 1,而 log 出来的居然是 0
复制代码
脑子:诶?那我点击 +1 按钮,就应该 log 出 加1后的值呀
现实:点击了 +1 按钮,打印出来的,却是旧的值!
因为这个 setState 不会马上去改变 state.n 的值,而是等一会儿再去改变,等谁呢?
等 console.log(this.state.n) 执行完了才改变 state.n 的值
所以说啊:setState 它是异步更新 state.n 的过程
所以,经常有人因为这个原因而造成 BUG
所以牛 x 写法是这样的

add() {
  this.setState(state => {       // 接受一个旧的 state
    return { n: state.n + 1 }    // 返回一个新的 state
  })
}

还是一样,把 state.n log 出来:
这时候 log 出新的 n,总不会写成 console.log(state.n) 吧?
因为这个 state.n,它是旧的!

  add() {
    this.setState(state => {  // 这是旧的 state
      const n = state.n + 1   // 这个 n 是新的 n
      console.log(n)          // 然后把新的 n 打印出来
      return { n }            // 缩写,原来是return { n: n } 
    })
  }

现在点击 +1 按钮,再看看 log,诶?是不是和 UI 同步了?
牛x写法也是异步执行的,但就是比第一种写法更好一点
所以,使用 state 的时候需要注意的一点就是:setState 不会马上去改变 state,最好使用函数去读新的值是会更好的
其实,简单的情况,可以用普通的方法写,但是稍微有一点复杂情况下,就一定一定要用 牛x 写法写,因为这种写法可以避免混淆 新旧的 state
总结

this.state.n += 1 无效?

其实 n 已经改变了,只不过 UI 不会自动更新而已
调用 setState 才会触发 UI 更新(异步更新)
因为 React 没有像 Vue 监听 data 一样监听 state

setState 会异步更新 UI

setState 之后,state 不会马上改变,马上读 state 会失败
所以更推荐的方式是 setState( 这里写函数 )

不推荐 this.setState(this.state)

React 希望我们不要修改旧 state(数据不可变)

这是一种函数式的理念

你可能感兴趣的:(react setState同步操作)