摘要:下面,我將從上到下挑選出能給自己一些啟發的源碼做注解。省略了很多代碼通過這段精簡的,我們看到,,返回的是一個構造函數,該函數原型繼承于,并將參數中定義的屬性合并到其中。
ReactClass.js
源文件: https://github.com/facebook/react/blob/master/src/isomorphic/classic/class/ReactClass.js
2017.4.9 更新 自15.5版本開始,createClass將不再包含到react核心庫,而需要從一個獨立的npm package - create-react-class獲取。更新說明
我們最常用的React.createClass方法就是在這個文件中定義的(JSX代碼最終都要轉換成createClass這種形式的)。這也是我閱讀react源碼過程中,打算詳細解讀的第一個文件。下面,我將從上到下挑選出能給自己一些啟發的源碼做注解。有些代碼,已有注釋,就不在這里粘貼了。包含__DEV__的代碼段,也暫且忽略。
"use strict";
"use strict";是es5語法中用來定義嚴格模式的。顧名思議,嚴格模式使得js引擎校驗js語法的時候,標準更加嚴格。一些在非嚴格模式下被忽略的非友好的語法,在嚴格模式下會直接報錯。所以,總是使用嚴格模式,使得js代碼更加安全。這是一個好習慣。
var ReactBaseClasses = require("ReactBaseClasses"); var ReactElement = require("ReactElement"); var ReactNoopUpdateQueue = require("ReactNoopUpdateQueue");
ReactBaseClasses定義了React.Component和React.PureComponent兩個類,此處不展開。
ReactElement定義了一些操作React Element的方法,比如creatEelment,cloneElement,createFactory等
ReactNoopUpdateQueue是默認的updater對象。當我們setState的時候,就會馬上調用updater.enqueueReplaceState方法,將新的state放入一個隊列中,異步處理。
var emptyObject = require("fbjs/lib/emptyObject"); var invariant = require("fbjs/lib/invariant"); var warning = require("fbjs/lib/warning");
fbjs是一個工具集,是獨立于react的另一個項目,被facebook不同項目所共享,如relay。
invariant用在一些強制條件不被滿足的地方,比如變量類型用錯。invariant在react項目中大量地使用,必須要細看一下。找到invariant文件的位置。繼續只關注值得學習的地方。
var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error( format.replace(/%s/g, function() { return args[argIndex++]; }) );
get新技能,原來string的replace方法,是可以遞歸調用的。
warning和invariant類似,也會在瀏覽器中輸出紅色的提示,只是warning輸出的是警告信息,消息體中帶有warning字樣。warning所在的文件位置。
type SpecPolicy = | "DEFINE_ONCE" | "DEFINE_MANY" | "OVERRIDE_BASE" | "DEFINE_MANY_MERGED"; // ... /** * @interface ReactClassInterface * @internal */ var ReactClassInterface: {[key: string]: SpecPolicy} = { mixins: "DEFINE_MANY", // ... }
要理解上面一段代碼,就必須要了解react所用的類型系統Flow了。
type SpecPolicy定義了一個枚舉類型。
注釋中的@interface讓我誤以為ReactClassInterface是一個接口類型,其實不然,查flow文檔,才確定其為Object Type。它規定這個object中的每個key必須是一個string,值必須是SpecPolicy類型。[key: string]中的key本身只是種注解而已,為了方便代碼的閱讀,沒有實際的意義,你可以把它改為name等任何字符串。
// ... 省略了很多代碼 var ReactClassComponent = function() {}; Object.assign( ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin, ); var ReactClass = { createClass: function(spec) { var Constructor = identity(function(props, context, updater) { this.props = props; this.context = context; this.refs = emptyObject; // ... }; Constructor.prototype = new ReactClassComponent(); Constructor.prototype.constructor = Constructor; // ... mixSpecIntoComponent(Constructor, spec); // ... return Constructor; } }
通過這段精簡的createClass,我們看到,createClass,返回的是一個構造函數,該函數原型繼承于ReactClassComponent,并將參數spec中定義的屬性合并到其prototype中。如果結合createClass的一個實例來看個文件,就更容易理解了。比如:
const Contacts = React.createClass({ propTypes: { }, getDefaultProps() { return { }; }, render() { return ( ); } });
基中,Contacts就是一個函數,一個構造函數。可以用來生成React.Component。
至此,這個800多行的React.createClass核心代碼,就理順了。
原文:http://react.apptravel.cn/article/59
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82386.html
摘要:查看創建核心函數源碼行調用函數創建是相關,不用管源碼行這個指的是調用創建,下面我們將會說到對象源碼行源碼行函數中,首先創建了一個,然后又創建了一個,它們兩者還是相互引用。 感謝 yck: 剖析 React 源碼解析,本篇文章是在讀完他的文章的基礎上,將他的文章進行拆解和加工,加入我自己的一下理解和例子,便于大家理解。覺得yck寫的真的很棒 。React 版本為 16.8.6,關于源碼的...
摘要:一更新的方式有三種渲染接下來,我們就來看下源碼二作用在提供的里渲染一個元素,并返回對該組件的引用常見的用法是這個官網網址源碼服務端使用方法渲染節點是讓服務端盡可能復用節點,提高性能元素容器應用渲染結束后,調用的函數錯誤抓取方法本質是返回 showImg(https://segmentfault.com/img/remote/1460000020064414?w=1240&h=641);...
摘要:一作用獲取目標的實例使用源碼可修改的不可變的對象沒見過這種寫法初始化對象,屬性初始值為解析源碼比較簡單,就是返回了帶有屬性的二作用從父組件中獲取子組件是的實例使用是沒有實例的,因為它是,所以沒有,所以不能通過來拿到實例將的傳給子組件,并綁定 showImg(https://segmentfault.com/img/remote/1460000019877636); 一、React.cr...
摘要:司徒正美的一款了不起的化方案,支持到。行代碼內實現一個胡子大哈實現的作品其實就是的了源碼學習個人文章源碼學習個人文章源碼學習個人文章源碼學習個人文章這幾片文章的作者都是司徒正美,全面的解析和官方的對比。 前言 在過去的一個多月中,為了能夠更深入的學習,使用React,了解React內部算法,數據結構,我自己,從零開始寫了一個玩具框架。 截止今日,終于可以發布第一個版本,因為就在昨天,我...
閱讀 2457·2019-08-30 15:53
閱讀 2572·2019-08-29 13:11
閱讀 2653·2019-08-29 12:45
閱讀 3486·2019-08-29 12:41
閱讀 2326·2019-08-26 10:14
閱讀 2154·2019-08-23 14:39
閱讀 2314·2019-08-23 12:38
閱讀 3378·2019-08-23 12:04