Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2018/06/05: batchedUpdate, 组件生命周期 #1

Open
Lxylona opened this issue Jun 5, 2018 · 2 comments
Open

2018/06/05: batchedUpdate, 组件生命周期 #1

Lxylona opened this issue Jun 5, 2018 · 2 comments

Comments

@Lxylona
Copy link
Owner

Lxylona commented Jun 5, 2018

1. batchedUpdate

前天就看了这个的源码了,是看setState源码的时候顺藤摸瓜看的。然后在纸上画了一张流程图,但是画的不尽人意,然后今天刚好看到了一张图,就是我理想中的那张图!

我之前看过Vue观察者模式的源码,React的setSate跟那个是两种思路,所以之前还没学React之前就已经很想看一下SetState的源码了,因此刚学了几天就迫不及待的看了……果然源码真的很难看懂。

参考了几篇文章:

React 源码剖析系列 - 解密 setState
从这篇文章接触到 事务 的概念,今天顺便看了一下事务的源码,因为才200多行似乎。
感觉事务很像Python中的装饰器,在原函数的基础上再执行一些别的东西,夹心饼干。

[React技术内幕] setState的秘密
写的非常好,很喜欢这种类型的文章,里面挺详细的讲解了源码又没有延伸太多的东西,适合我这种小白。看完画了一张流程图,大致知道了setState的整个基本流程是怎样的了。

Change Detection And Batch Update(写的很棒不过只看了React那一部分)

批量更新DOM(Vue.nextTick与React的setState分析笔记)

2. Transaction 事务

看了源码,知道它的作用但是……暂时不太理解他在React中到底充当着怎样一个角色。React又如何管理这些事务呢?

3. 组件的生命周期

从某篇文章里顺了一张图:

啦啦,顺了这样一张图

似乎没遇到什么难点。不过看到一篇文章,那里写着:不要在componentWillUpdate中执行setState。本来不知道为什么,不过刚好看过了setState的源码,有点印象,所以回去翻了一下,在重置state之前调用了这个函数,所以应该是死循环的问题。

4. Diff算法

之前学Vue的时候看过一点Diff算法的思想,但是因为那段时间一直在面试所以没有时间看,后来也就懒得看了,不过每次在想象框架里面的运作的时候到了这一步就觉得很膈应。因此今天晚上又重新在看Diff算法了……
现在在看这一篇,还没看完:React 源码剖析系列 - 不可思议的 react diff

4. 一些疑惑

1. 事务

我不太能理解这一块。
好吧我对事务的理解就是很小的一个点,setState那个点我懂了。但是没懂在整个React的运行过程中具体怎么管理事务的?

var flushBatchedUpdates = function() {
  while (dirtyComponents.length) {
    if (dirtyComponents.length) {
      //从事务pool中获得事务实例
      var transaction = ReactUpdatesFlushTransaction.getPooled();
      transaction.perform(runBatchedUpdates, null, transaction);
      //释放实例
      ReactUpdatesFlushTransaction.release(transaction);
    }
    //......
  }
};

从这里看是第一个事务结束之后从事务池拿出一个新的事务,然后再进行update。那么事务在哪里生出来的?
晚上看到了一篇文章,Change Detection And Batch Update
里面提到的是类似于click等事件会被包裹在一个事务中,或许这就是事务的来源吧。明天有时间捋一下……

@arcthur
Copy link

arcthur commented Jun 6, 2018

setState 如果做同步,怎么做,源码里有对应的体现么
在每一个生命周期里加 setState 会有什么效果

@Lxylona Lxylona changed the title 学习笔记:2018/06/05 2018/06/05: batchedUpdate, 组件生命周期 Jun 10, 2018
@Lxylona
Copy link
Owner Author

Lxylona commented Jun 10, 2018

@arcthur

  1. 同步可以在 setState 中传入函数而不是对象,源码中是把对象逐个合并到 preState 中,如果传入函数,函数传入的参数是 nextState 。或者用 setTimeout 这类函数包裹 setState,因此下一个 tick 的时候没有异步队列在更新,因此遇到一个 setState 都会触发 update。

  2. 组件在 componentWillMount, componentDidMount, componentWillReceiveProps 中可以使用 setState, 但是每个周期函数中的 setState 都会合成一块的(就是放在同一个异步队列中)。 不过不同生命周期之间的setState就是同步的,我不知道生命周期函数怎么实现的,不过我猜每一个生命周期放在一个单独的事务里面?我去看一下组件初次渲染的源码。
    在setState执行的时候有执行到一个函数叫 _performComponentUpdate ,这个函数先执行了 componentWillUpdate, 然后执行 render, 最后执行 componentDidUpdate,所以不能在componentWillUpdate,componentDidUpdate 中使用 setState,因此会导致循环调用然后造成栈溢出。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants