自己写一个 react 5.setState
setState 这个 api 里面做了些啥 ,网上有很多资料,典型的是关于源代码里面的一幅 ASCII 图画
/* * <pre>
 *                       wrappers (injected at creation time)
 *                                      +        +
 *                                      |        |
 *                    +-----------------|--------|--------------+
 *                    |                 v        |              |
 *                    |      +---------------+   |              |
 *                    |   +--|    wrapper1   |---|----+         |
 *                    |   |  +---------------+   v    |         |
 *                    |   |          +-------------+  |         |
 *                    |   |     +----|   wrapper2  |--------+   |
 *                    |   |     |    +-------------+  |     |   |
 *                    |   |     |                     |     |   |
 *                    |   v     v                     v     v   | wrapper
 *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
 * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
 * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | +---+ +---+   +---------+   +---+ +---+ |
 *                    |  initialize                    close    |
 *                    +-----------------------------------------+
 * </pre>
 */
和相关的测试用例
  this.setState({val: this.state.val + 1});    console.log(this.state.val);    
    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    
    setTimeout(() => {
      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  
      this.setState({val: this.state.val + 1});
      console.log(this.state.val); 
    }, 0);
  }
综合上面的资料,我理解setState的运行是这样的
开启一个标识->setState只负责把所有的state推进队列->推进完毕,重置标识,批量更新state这时候我就疑惑了,我setState内部怎么知道其他的setState完毕了没有(黑人问号)。这时候参考一些迷你react,发现他们都是用浏览器原生的延迟实现
https://github.com/developit/preact/blob/2399c49dad2dd9c932e74bfe56dfd577c2d0cde2/src/util.js#L19
这个是整体设计的思路就不一样,没办法参考,我只能看react本身。不过代码非常庞大,有没有什么快捷的方法呢?有的,看chrome调用栈,如图

这个调用栈是官方一个例子的,点击某个按钮,setState改变toggle状态
https://codepen.io/gaearon/pen/xEmzGg?editors=0010
可以看出来,用户点击事件和setState之间,还有很多重调用,在这些里面调用了batchedUpdates,个人觉得react的合成事件与setState之间有相互配合,也就是说我在写react组件时的传递的点击事件,并不是直接调用了setState的,中间还有包裹函数。于是思路就清晰了,代码实现起来也很快,我觉得最关键的是这一步: https://github.com/p2227/diyReact/blob/ed45e6be54dc95b76f0a755352118eb1ed3ea890/src/stage4-transaction.js#L372
而且上面的测试用例也是跑通过的。
不知道我理解得对不对,欢迎抛砖引玉
以上是 自己写一个 react 5.setState 的全部内容, 来源链接: utcz.com/z/264565.html
