1 分钟带你 get React setState 面试要点

用户头像
🇯 🇹 🇷
关注
发布于: 2020 年 10 月 22 日
1分钟带你get React setState 面试要点

前言: 对于React的初学者来说,setState这个API是再亲切不过了,但你真的了解它了吗?面试时工作是,你能讲清楚他吗?



我们来先看几道题目吧?



  • Q1:

...
state = {
count: 0
}
componentDidMount() {
this.setState({count: this.state.count + 1})
console.log(this.state.count)
this.setState({count: this.state.count + 1})
console.log(this.state.count)
this.setState({count: this.state.count + 1})
console.log(this.state.count)
setTimeout(() => {
console.log(this.state.count)
this.setState({count: this.state.count + 1})
console.log(this.state.count)
this.setState({count: this.state.count + 1})
console.log(this.state.count)
}, 0)
console.log(this.state.count, 'end')
}
...
  • Q2:

...
state = {
count: 0
}
componentDidMount() {
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count)})
console.log(this.state.count)
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count)})
console.log(this.state.count)
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count)})
console.log(this.state.count, 'end')
}
...

如果你能很清晰的回答出来,那么恭喜你



setState 是同步还是异步?

我们先来看Q1的答案

console.log ---- down ---
0
0
0
0 'end'
3
4

从表面上来看,在同步代码块中他是异步更新的,在异步代码块中他是同步的更新的,但是我想说的是能够由React控制的它就是异步更新,不能由React控制的他是同步更新!

  • React控制的

  • React的生命周期

  • React注册的事件

  • React不能控制的

  • setTimeout、setInterval

  • 自定义注册的DOM事件

要搞清楚这些,要需要理解2个概念bathUpdate,Transacation

batchUpdate批量更新

一句话搞定就是,这个有点机制像函数防抖,React会尽量的减少不必要的刷新,能一起更新的就一起更新了。

Transacation事务机制

一句话搞定就是,这个就是实现batchUpdate的模型Transaction,他看起来就像requestAnimationFrame;这也是React实现异步渲染的一个重要基石,每当React获取控制权的时候就会执行batchUpdate,当React失去控制权的时候,setState就是同步代码一样。

setState 是否合并操作?

再来看看Q2的答案

console.log ---- down ---
0
0
0 'end'
3
3
3

结合Q1的例子来看,当setState传入的第一个参数是object数据类型那么它就会合并,传入的是function数据类型,那么它就不会合并;可以想象如果传入的是oject数据类型,它大可以通过Object.assgin这样的API将其合并,如果是function数据类型化,依次执行

小结

本文主要描述了React setState 的两个现象,操作是否合并和是否异步更新。

  • setState 操作合并

  • 当第一个传入的参数是object数据类型它就会合并,类型调用了Object.assgin

  • 当参数类型是function数据类型时,不会合并

  • setState 是否异步

  • React获得控制权的时候,它就是异步执行

  • React什么周期内

  • React注册的事件内

  • 当React丧失控制权的时候,它就是同步执行

  • setTimeout、Promise 等异步函数

  • 自定义注册DOM事件等

小测验,看你都掌握了吗?

赘述了这么多,下面的code对你来说一定是小菜一碟了吧?

...
state = {
count: 0
}
componentDidMount() {
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count)})
console.log(this.state.count)
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count)})
console.log(this.state.count)
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count)})
console.log(this.state.count, 'end')
}
handleCount = () => {
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
Promise.resolve().then(() => {
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
})
console.log(this.state.count, 'end1');
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count, '1')})
console.log(this.state.count)
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count, '2')})
console.log(this.state.count)
this.setState(state => ({count: state.count + 1}), () => {console.log(this.state.count, '3')})
console.log(this.state.count, 'end2')
}

参考:

发布于: 2020 年 10 月 22 日 阅读数: 12
用户头像

🇯 🇹 🇷

关注

读书点亮生活, 2019.01.16 加入

Polo MI

评论

发布
暂无评论
1分钟带你get React setState 面试要点