码云笔记前端博客
Home > 每日·壹题 > 第12题:为什么有时连续多次setState只有一次生效?

第12题:为什么有时连续多次setState只有一次生效?

2019-10-04 分类:每日·壹题 作者:码云 阅读(53)

本文共计976个字,预计阅读时长需要3分钟。

第12题:为什么有时连续多次setState只有一次生效?
例如下面的代码,两次打印出的结果是相同的:

1
2
3
4
5
6
7
8
componentDidMount() {
    this.setState({ index: this.state.index + 1 }, () => {
      console.log(this.state.index);
    })
    this.setState({ index: this.state.index + 1 }, () => {
      console.log(this.state.index);
    })
  }

原因就是 React会批处理机制中存储的多个 setState进行合并,来看下 React源码中的 _assign函数,类似于 Object的 assign:

1
_assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial);

如果传入的是对象,很明显会被合并成一次,所以上面的代码两次打印的结果是相同的:

1
2
3
4
5
Object.assign(
  nextState,
  {index: state.index+ 1},
  {index: state.index+ 1}
)

注意, assign函数中对函数做了特殊处理,处理第一个参数传入的是函数,函数的参数 preState是前一次合并后的结果,所以计算结果是准确的:

1
2
3
4
5
6
7
8
9
10
11
12
componentDidMount() {
    this.setState((state, props) => ({
        index: state.index + 1
    }), () => {
      console.log(this.state.index);
    })
    this.setState((state, props) => ({
        index: state.index + 1
    }), () => {
      console.log(this.state.index);
    })
  }

所以上面的代码两次打印的结果是不同的。

最佳实践

React会对多次连续的 setState进行合并,如果你想立即使用上次 setState后的结果进行下一次 setState,可以让 setState 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数。

「除特别注明外,本站所有文章均为码云笔记原创,转载请保留出处!」

赞(13) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
13

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 0 条评论 - 第12题:为什么有时连续多次setState只有一次生效?

博客简介

码云笔记 mybj123.com,一个专注Web前端开发技术的博客,主要记录和总结博主在前端开发工作中常用的实战技能及前端资源分享,分享各种科普知识和实用优秀的代码,以及分享些热门的互联网资讯和福利!码云笔记有你更精彩!
更多博客详情请看关于博客

精彩评论

站点统计

  • 文章总数: 458 篇
  • 分类数目: 13 个
  • 独立页面: 8 个
  • 评论总数: 215 条
  • 链接总数: 14 个
  • 标签总数: 1011 个
  • 建站时间: 495 天
  • 访问总量: 8647989 次
  • 最近更新: 2019年10月21日