国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

深入研究React中setState源碼

2024-05-06 15:24:22
字體:
來源:轉載
供稿:網友

React作為一門前端框架,雖然只是focus在MVVM中的View部分,但還是實現了View和model的綁定。修改數據的同時,可以實現View的刷新。這大大簡化了我們的邏輯,只用關心數據流的變化,同時減少了代碼量,使得后期維護也更加方便。這個特性則要歸功于setState()方法。React中利用隊列機制來管理state,避免了很多重復的View刷新。下面我們來從源碼角度探尋下setState機制。

1 還是先聲明一個組件,從最開始一步步來尋源;

class App extends Component {  //只在組件重新加載的時候執行一次  constructor(props) {    super(props);   //..  }   //other methods}//ReactBaseClasses.js中如下:這里就是setState函數的來源;//super其實就是下面這個函數function ReactComponent(props, context, updater) { this.props = props; this.context = context; this.refs = emptyObject; // We initialize the default updater but the real one gets injected by the // renderer. this.updater = updater || ReactNoopUpdateQueue;}ReactComponent.prototype.setState = function (partialState, callback) { this.updater.enqueueSetState(this, partialState); if (callback) {  this.updater.enqueueCallback(this, callback, 'setState'); }};

所以主要來看是否傳入了updater參數,也就是說何時進行 new 組件;具體的updater參數是怎么傳遞進來的,以及是那個對象,參見

react源碼分析系列文章下面的react中context updater到底是如何傳遞的

這里直接說結果,updater對象其實就是ReactUpdateQueue.js 中暴漏出的ReactUpdateQueue對象;

2 既然找到了setState之后執行的動作,我們在一步步深入進去

class Root extends React.Component { constructor(props) {  super(props);  this.state = {   count: 0  }; } componentDidMount() {  let me = this;  me.setState({   count: me.state.count + 1  });  console.log(me.state.count);  // 打印出0  me.setState({   count: me.state.count + 1  });  console.log(me.state.count);  // 打印出0  setTimeout(function(){   me.setState({    count: me.state.count + 1   });   console.log(me.state.count);  // 打印出2  }, 0);  setTimeout(function(){   me.setState({    count: me.state.count + 1   });   console.log(me.state.count);  // 打印出3  }, 0); } render() {  return (   <h1>{this.state.count}</h1>  ) }}ReactComponent.prototype.setState = function (partialState, callback) { this.updater.enqueueSetState(this, partialState); if (callback) {  this.updater.enqueueCallback(this, callback, 'setState'); }};

ReactUpdateQueue.js

var ReactUpdates = require('./ReactUpdates');function enqueueUpdate(internalInstance) { ReactUpdates.enqueueUpdate(internalInstance);};function getInternalInstanceReadyForUpdate(publicInstance, callerName) { //在ReactCompositeComponent.js中有這樣一行代碼,這就是其來源; // Store a reference from the instance back to the internal representation  //ReactInstanceMap.set(inst, this); var internalInstance = ReactInstanceMap.get(publicInstance); //返回的是在ReactCompositeComponent.js中construct函數返回的對象;ReactInstance實例對象并不是簡單的new 我們寫的組件的實例對象,而是經過instantiateReactComponent.js中ReactCompositeComponentWrapper函數包裝的對象;詳見 創建React組件方式以及源碼分析.md return internalInstance;};var ReactUpdateQueue = {//。。。。省略其他代碼 enqueueCallback: function (publicInstance, callback, callerName) {  ReactUpdateQueue.validateCallback(callback, callerName);  var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);  if (!internalInstance) {   return null;  }//這里將callback放入組件實例的_pendingCallbacks數組中;  if (internalInstance._pendingCallbacks) {   internalInstance._pendingCallbacks.push(callback);  } else {   internalInstance._pendingCallbacks = [callback];  }  // TODO: The callback here is ignored when setState is called from  // componentWillMount. Either fix it or disallow doing so completely in  // favor of getInitialState. Alternatively, we can disallow  // componentWillMount during server-side rendering.  enqueueUpdate(internalInstance); }, enqueueSetState: function (publicInstance, partialState) {  var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');  if (!internalInstance) {   return;  }  //這里,初始化queue變量,同時初始化 internalInstance._pendingStateQueue = [ ] ;  //對于 || 的短路運算還是要多梳理下  //queue數組(模擬隊列)中存放著setState放進來的對象;  var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);  //這里將partialState放入queue數組中,也就是internalInstance._pendingStateQueue 數組中,此時,每次setState的partialState,都放進了React組件實例對象上的_pendingStateQueue屬性中,成為一個數組;  queue.push(partialState);  enqueueUpdate(internalInstance); },};module.exports = ReactUpdateQueue;            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 博湖县| 张家川| 通山县| 镇宁| 延长县| 云安县| 永修县| 德令哈市| 咸丰县| 应用必备| 黄浦区| 安塞县| 凤冈县| 板桥市| 清苑县| 望城县| 南和县| 福泉市| 淅川县| 泰州市| 长寿区| 乐业县| 朝阳区| 虞城县| 崇州市| 饶阳县| 同江市| 通江县| 华安县| 贵州省| 泸州市| 长丰县| 秦皇岛市| 玉山县| 虹口区| 沙坪坝区| 合作市| 佛教| 吴江市| 五大连池市| 桦南县|