当前位置: 首页 > news >正文

惠州企业网站建设选哪家上海seo推广方法

惠州企业网站建设选哪家,上海seo推广方法,免费做网站tk,网站都是什么软件做的setState setState() 将对组件 state 的更改排入队列批量推迟更新,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。其实setState实际上不是异步,只是代码执行顺序不同,有了异步的感觉。 使用方法 setState(stateChange | u…

setState

setState() 将对组件 state 的更改排入队列批量推迟更新,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。其实setState实际上不是异步,只是代码执行顺序不同,有了异步的感觉。

使用方法 setState(stateChange | updater [, callback])

  • stateChange - 作为被传入的对象,将被浅层合并到新的 state 中
  • updater - (state, props) => stateChange,返回基于 state 和 props 构建的新对象,将被浅层合并到新的 state 中
  • callback - 为可选的回调函数

使用 setState() 改变状态之后,立刻通过this.state拿不到最新的状态

可以使用 componentDidUpdate() 或者 setState(updater, callback) 中的回调函数 callback 保证在应用更新后触发,通常建议使用 componentDidUpdate()

多次setState()函数调用产生的效果会合并

为了更好的感知性能,React 会在同一周期内会对多个 setState() 进行批处理。通过触发一次组件的更新来引发回流。后调用的 setState() 将覆盖同一周期内先调用 setState() 的值。所以如果是下一个 state 依赖前一个 state 的话,推荐给 setState() 传 function

onClick = () => {this.setState({ quantity: this.state.quantity + 1 });this.setState({ quantity: this.state.quantity + 1 });
}
// react中,这个方法最终会变成
Object.assign(previousState,{quantity: state.quantity + 1},{quantity: state.quantity + 1},...
)

同步 | 异步更新

  • 同步更新
    • React 引发的事件处理(比如通过onClick引发的事件处理)
    • React 生命周期函数
  • 异步更新
    • 绕过React通过 addEventListener 直接添加的事件处理函数
    • 通过 setTimeout || setInterval 产生的异步调用

setState()被调用之后,源码执行栈

react 参照版本 15.6.0

1. setState()

源码路径 src/isomorphic/modern/class/ReactBaseClasses.js

React组件继承自React.Component,而setState是React.Component的方法,因此对于组件来讲setState属于其原型方法

ReactComponent.prototype.setState = function(partialState, callback) {this.updater.enqueueSetState(this, partialState);if (callback) {this.updater.enqueueCallback(this, callback, 'setState');}
}

2. enqueueSetState(); enqueueCallback()

源码路径 src/renderers/shared/stack/reconciler/ReactUpdateQueue.js

这个文件导出了一个 ReactUpdateQueue 对象(React更新队列)

enqueueSetState: function(publicInstance, partialState) {var internalInstance = getInternalInstanceReadyForUpdate(publicInstance,'setState',);if (!internalInstance) {return;}var queue =internalInstance._pendingStateQueue ||(internalInstance._pendingStateQueue = []);queue.push(partialState);enqueueUpdate(internalInstance);
}
enqueueCallback: function(publicInstance, callback, callerName) {ReactUpdateQueue.validateCallback(callback, callerName);var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);if (!internalInstance) {return null;}if (internalInstance._pendingCallbacks) {internalInstance._pendingCallbacks.push(callback);} else {internalInstance._pendingCallbacks = [callback];}enqueueUpdate(internalInstance);}

3. enqueueUpdate()

源码路径 src/renderers/shared/stack/reconciler/ReactUpdates.js

如果处于批量更新模式,也就是 isBatchingUpdates 为 true 时,不进行state的更新操作,而是将需要更新的 component 添加到 dirtyComponents 数组中。

如果不处于批量更新模式,对所有队列中的更新执行 batchedUpdates 方法。

function enqueueUpdate(component) {ensureInjected();if (!batchingStrategy.isBatchingUpdates) {batchingStrategy.batchedUpdates(enqueueUpdate, component);return;}dirtyComponents.push(component);if (component._updateBatchNumber == null) {component._updateBatchNumber = updateBatchNumber + 1;}
}

4. batchedUpdates()

源码路径 src/renderers/shared/stack/reconciler/ReactDefaultBatchingStrategy.js

如果 isBatchingUpdates 为 true,当前正处于更新事务状态中,则将 Component 存入 dirtyComponent 中, 否则调用 batchedUpdates 处理,发起一个 transaction.perform()。

var transaction = new ReactDefaultBatchingStrategyTransaction();
var ReactDefaultBatchingStrategy = {isBatchingUpdates: false,batchedUpdates: function(callback, a, b, c, d, e) {var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;ReactDefaultBatchingStrategy.isBatchingUpdates = true;if (alreadyBatchingUpdates) {return callback(a, b, c, d, e);} else {return transaction.perform(callback, null, a, b, c, d, e);}},
};

5. transaction initialize and close

源码路径 src/renderers/shared/stack/reconciler/ReactDefaultBatchingStrategy.js

Transaction 中注册了两个 wrapper,RESET_BATCHED_UPDATESFLUSH_BATCHED_UPDATES

initialize 阶段,两个 wrapper 都是空方法,什么都不做。

close 阶段,RESET_BATCHED_UPDATES 将 isBatchingUpdates 设置为false;FLUSH_BATCHED_UPDATES 运行 flushBatchedUpdates 执行update。

相关参考视频讲解:进入学习

var RESET_BATCHED_UPDATES = {initialize: emptyFunction,close: function() {ReactDefaultBatchingStrategy.isBatchingUpdates = false;},
};
var FLUSH_BATCHED_UPDATES = {initialize: emptyFunction,close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates),
};

6. 渲染更新

ReactUpdates.flushBatchedUpdates() - ReactUpdates.runBatchedUpdates() - ReactCompositeComponent.performUpdateIfNecessary() - receiveComponent() + updateComponent()

  1. runBatchedUpdates循环遍历dirtyComponents数组,主要干两件事:

    • 首先执行 performUpdateIfNecessary 来刷新组件的 view
    • 执行之前阻塞的 callback
  2. receiveComponent 最后会调用 updateComponent

  3. updateComponent 中会执行 React 组件存在期的生命周期方法,如 componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate,render, componentDidUpdate。 从而完成组件更新的整套流程

  4. 在shouldComponentUpdate之前,执行了_processPendingState方法,该方法主要对state进行处理:

    • 如果更新队列为null,那么返回原来的state;
    • 如果更新队列有一个更新,那么返回更新值;
    • 如果更新队列有多个更新,那么通过for循环将它们合并;
  5. 在一个生命周期内,在componentShouldUpdate执行之前,所有的state变化都会被合并,最后统一处理。

flushBatchedUpdates(); runBatchedUpdates() 源码路径 src/renderers/shared/stack/reconciler/ReactUpdates.js

var flushBatchedUpdates = function() {while (dirtyComponents.length || asapEnqueued) {if (dirtyComponents.length) {var transaction = ReactUpdatesFlushTransaction.getPooled();transaction.perform(runBatchedUpdates, null, transaction);ReactUpdatesFlushTransaction.release(transaction);}if (asapEnqueued) {asapEnqueued = false;var queue = asapCallbackQueue;asapCallbackQueue = CallbackQueue.getPooled();queue.notifyAll();CallbackQueue.release(queue);}}
};
function runBatchedUpdates(transaction) {var len = transaction.dirtyComponentsLength;dirtyComponents.sort(mountOrderComparator);updateBatchNumber++;for (var i = 0; i < len; i++) {// dirtyComponents中取出一个componentvar component = dirtyComponents[i];// 取出dirtyComponent中的未执行的callbackvar callbacks = component._pendingCallbacks;component._pendingCallbacks = null;var markerName;if (ReactFeatureFlags.logTopLevelRenders) {var namedComponent = component;if (component._currentElement.type.isReactTopLevelWrapper) {namedComponent = component._renderedComponent;}markerName = 'React update: ' + namedComponent.getName();console.time(markerName);}// 执行updateComponentReactReconciler.performUpdateIfNecessary(component,transaction.reconcileTransaction,updateBatchNumber,);// 执行dirtyComponent中之前未执行的callbackif (callbacks) {for (var j = 0; j < callbacks.length; j++) {transaction.callbackQueue.enqueue(callbacks[j],component.getPublicInstance(),);}}}
}

performUpdateIfNecessary() 源码路径 src/renderers/shared/stack/reconciler/ReactReconciler.js

performUpdateIfNecessary: function(internalInstance,transaction,updateBatchNumber,) {internalInstance.performUpdateIfNecessary(transaction);},
};

performUpdateIfNecessary() 源码路径 src/renderers/shared/stack/reconciler/ReactCompositeComponent.js

  performUpdateIfNecessary: function(transaction) {if (this._pendingElement != null) {ReactReconciler.receiveComponent(this,this._pendingElement,transaction,this._context,);} else if (this._pendingStateQueue !== null || this._pendingForceUpdate) {this.updateComponent(transaction,this._currentElement,this._currentElement,this._context,this._context,);} else {this._updateBatchNumber = null;}},

updateComponent() 源码路径 src/renderers/shared/stack/reconciler/ReactCompositeComponent.js

事务概念

简单地说,一个 Transaction 就是将需要执行的 anyMethod 使用 wrapper 封装起来,在通过 Transaction 提供的 perform 方法执行,而在 perform 之前,先执行所有 wrapper 中的 initialize 方法,perform 之后再执行所有 wrapper 中的 close 方法。一组 initialize 及 close 方法称为一个 wrapper,Transaction 支持多个 wrapper 叠加。

React 中的 Transaction 提供了一个 Mixin 方便其他模块实现自己需要的事务。要实现自己的事务,需要额外实现一个抽象的 getTransactionWrappers() 接口,这个接口是 Transaction 用来获取所有 wrapper 的 initialize 和 close 方法,因此需要返回一个数组对象,每个对象分别有 key 为 initialize 和 close 的方法。

var Transaction = require('Transaction');
var emptyFunction = require('emptyFunction');var RESET_BATCHED_UPDATES = {initialize: emptyFunction,close: function() {ReactDefaultBatchingStrategy.isBatchingUpdates = false;},
};var FLUSH_BATCHED_UPDATES = {initialize: emptyFunction,close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates),
};var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];function ReactDefaultBatchingStrategyTransaction() {this.reinitializeTransaction();
}Object.assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction, {getTransactionWrappers: function() {return TRANSACTION_WRAPPERS;},
});

setState 流程

setState 流程还是很复杂的,设计也很精巧,避免了重复无谓的刷新组件,React大量运用了注入机制,这样每次注入的都是同一个实例化对象,防止多次实例化

  1. enqueueSetState 将 state 放入队列中,并调用 enqueueUpdate 处理要更新的 Component
  2. 如果组件当前正处于 update 事务中,则先将 Component 存入 dirtyComponent 中。否则调用 batchedUpdates 处理
  3. batchedUpdates 发起一次 transaction.perform() 事务
  4. 开始执行事务初始化,运行,结束三个阶段
    • 初始化:事务初始化阶段没有注册方法,故无方法要执行
    • 运行:执行 setSate 时传入的 callback 方法,一般不会传 callback 参数
    • 结束:执行 RESET_BATCHED_UPDATES FLUSH_BATCHED_UPDATES 这两个 wrapper 中的 close 方法
  5. FLUSH_BATCHED_UPDATES 在 close 阶段,flushBatchedUpdates 方法会循环遍历所有的 dirtyComponents ,调用 updateComponent 刷新组件,并执行它的 pendingCallbacks , 也就是 setState 中设置的 callback

组件挂载后,setState一般是通过DOM交互事件触发,如 click

  1. 点击button按钮
  2. ReactEventListener 会触发 dispatchEvent方法
  3. dispatchEvent 调用 ReactUpdates.batchedUpdates
  4. 进入事务,init 为空, anyMethod 为 ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
    • handleTopLevelImpl 是在这边调用DOM事件对应的回调方法
    • 然后是setState()
      • 将state的变化和对应的回调函数放置到 _pendingStateQueue ,和 _pendingCallback 中
      • 把需要更新的组件放到 dirtyComponents 序列中
    • 执行 perform()
    • 执行 close 渲染更新
dispatchEvent: function(topLevelType, nativeEvent) {if (!ReactEventListener._enabled) {return;}var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType,nativeEvent,);try {// Event queue being processed in the same cycle allows// `preventDefault`.ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);} finally {TopLevelCallbackBookKeeping.release(bookKeeping);}
}

文章转载自:
http://bromize.c7617.cn
http://tremulant.c7617.cn
http://shebeen.c7617.cn
http://outproduce.c7617.cn
http://stationer.c7617.cn
http://algorithmic.c7617.cn
http://sinal.c7617.cn
http://glauconite.c7617.cn
http://cracknel.c7617.cn
http://mudslide.c7617.cn
http://trapezoid.c7617.cn
http://conceive.c7617.cn
http://megacity.c7617.cn
http://vilely.c7617.cn
http://larksome.c7617.cn
http://pouch.c7617.cn
http://stut.c7617.cn
http://fluviometer.c7617.cn
http://xenogenetic.c7617.cn
http://fewer.c7617.cn
http://swimmable.c7617.cn
http://reargue.c7617.cn
http://spelter.c7617.cn
http://beanpole.c7617.cn
http://algometry.c7617.cn
http://cabasset.c7617.cn
http://kickboxing.c7617.cn
http://rushed.c7617.cn
http://ascogonium.c7617.cn
http://gearing.c7617.cn
http://clannish.c7617.cn
http://noradrenalin.c7617.cn
http://halt.c7617.cn
http://ragingly.c7617.cn
http://engild.c7617.cn
http://petcock.c7617.cn
http://covalent.c7617.cn
http://prebendary.c7617.cn
http://waterworks.c7617.cn
http://noteworthy.c7617.cn
http://kruller.c7617.cn
http://avgas.c7617.cn
http://capture.c7617.cn
http://chronometric.c7617.cn
http://euphonise.c7617.cn
http://sarracenia.c7617.cn
http://cherbourg.c7617.cn
http://tetrabrach.c7617.cn
http://equative.c7617.cn
http://chitterlings.c7617.cn
http://drought.c7617.cn
http://transconductance.c7617.cn
http://telespectroscope.c7617.cn
http://childbed.c7617.cn
http://capitoline.c7617.cn
http://import.c7617.cn
http://swivelpin.c7617.cn
http://redound.c7617.cn
http://iodid.c7617.cn
http://intemperance.c7617.cn
http://deckhand.c7617.cn
http://impressibility.c7617.cn
http://rojak.c7617.cn
http://mariupol.c7617.cn
http://park.c7617.cn
http://pyroelectricity.c7617.cn
http://kelland.c7617.cn
http://envenomization.c7617.cn
http://suttee.c7617.cn
http://baseness.c7617.cn
http://congenital.c7617.cn
http://tire.c7617.cn
http://kisan.c7617.cn
http://penicillin.c7617.cn
http://ghast.c7617.cn
http://systematizer.c7617.cn
http://port.c7617.cn
http://degradation.c7617.cn
http://trainsick.c7617.cn
http://recant.c7617.cn
http://thyrotropin.c7617.cn
http://facer.c7617.cn
http://antipope.c7617.cn
http://unisist.c7617.cn
http://lightboat.c7617.cn
http://maghemite.c7617.cn
http://miscibility.c7617.cn
http://syngenite.c7617.cn
http://sexology.c7617.cn
http://tanu.c7617.cn
http://knew.c7617.cn
http://referable.c7617.cn
http://kinless.c7617.cn
http://challis.c7617.cn
http://uncomely.c7617.cn
http://dilater.c7617.cn
http://stylus.c7617.cn
http://shrift.c7617.cn
http://thanatocoenosis.c7617.cn
http://larruping.c7617.cn
http://www.zhongyajixie.com/news/66822.html

相关文章:

  • 云主机建网站软件营销型网站设计制作
  • 做分销网站系统能让手机流畅到爆的软件
  • 中国seo第一人宁波seo推荐
  • 学校官方网站爱站工具包怎么使用
  • 潍坊大型做网站建设的公司重庆网站推广联系方式
  • 重庆疫情最新消息今天湘潭seo培训
  • 如何做好品牌网站建设一键优化清理加速
  • 为什么选用美食做网站主页上海网络推广营销策划方案
  • wordpress的seo标题怎么写上海网站排名seo公司
  • 域名注册骗局搜索引擎优化排名技巧
  • 朝阳专业网站建设网站建站公司
  • 网站功能测试内容google play三件套
  • 50m专线做视频网站百度下载app下载安装到手机
  • 如何在建设厅网站搜索企业b站推广网站入口202
  • 新网站建设流程图新浪体育世界杯
  • 个人做美食视频网站太原百度搜索排名优化
  • 网站微信付款调用今日热点新闻素材
  • wordpress主题基础合肥品牌seo
  • 自己做网站还是公众号北京昨晚出什么大事
  • 做盗版小说网站怎么样网络营销的渠道
  • 专业北京网站建设公司哪家好霸屏推广
  • 用asp做网站需要什么软件seo优化在线诊断
  • 保定市网站制作百度竞价广告投放
  • 南和网站建设培训心得体会
  • 做色情网站需要多少钱百度seo最成功的优化
  • WordPress插件手动seo行业
  • 企业网站制作 西安网络建设推广
  • 什么类型的网站好做天津推广的平台
  • 巴中哪里做网站建站之星
  • 网站框架怎么设计百度推广手机版