自己写一个 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调用栈,如图

自己写一个 react 5.setState

这个调用栈是官方一个例子的,点击某个按钮,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

回到顶部