react源碼解析(組件聲明與初始化)

 <body>
    <div id="container"></div>
    <script type="text/babel">
        class Hello extends React.Component{
            render(){
                return(
                    <div>
                        hello world
                    </div>
                )
            }
        }
        ReactDOM.render(<Hello/>,document.getElementById('container'));
        console.log(<Hello/>);
       //這里會(huì)發(fā)現(xiàn)<div>標(biāo)簽也被識(shí)別為react的元素
        console.log(<Hello><div>這是hello組件</div></Hello>);
    </script>
    </body>

運(yùn)行結(jié)果截圖


image.png

image.png

image.png

通過(guò)紅色框可以看出,<Hello><div>...</div></Hello> props中增加了children的字段鹃操,同理遗锣,如果我們進(jìn)行多層的組件嵌套,其實(shí)就是在父對(duì)象的props中增加children字段及對(duì)應(yīng)的描述值橱夭,也就是js對(duì)象的多層嵌套

1.組件的聲明
接下來(lái)我們從class Hello extends React.Component來(lái)分析
我們打開react.js的文件


image.png

可以看到react的對(duì)象中有一個(gè)Componenet:ReactComponent屬性緊接著我們?nèi)タ匆幌翿eactComponent


image.png

image.png

image.png

可以看出ReactComponent的原型上有一個(gè)setState方法也就是我們?cè)贖ello類的構(gòu)造函數(shù)我們可以直接覆寫該方法

2.組件的初始化(組件類必須擁有render方法輸出類似<div>hello world</div>的結(jié)構(gòu)并掛載到真實(shí)DOM上,才能觸發(fā)組件的生命周期并成為DOM樹的一部分)
我們把上面的代碼放到babel的解析其中桑逝,得到如下代碼

var Hello = function (_React$Component) {
//這里實(shí)現(xiàn)的是ReactComponent的繼承
    _inherits(Hello, _React$Component);

    function Hello() {
        _classCallCheck(this, Hello);

        return _possibleConstructorReturn(this, (Hello.__proto__ || Object.getPrototypeOf(Hello)).apply(this, arguments));
    }
//重點(diǎn)在這里,原來(lái)render方法的實(shí)現(xiàn)是調(diào)用React.createElement
    _createClass(Hello, [{
        key: "render",
        value: function render() {
            return React.createElement(
                "div",
                null,
                "hello world"
            );
        }
    }]);

    return Hello;
}(React.Component);

所以我們要去React.createElement的實(shí)現(xiàn)

ReactElement.createElement = function (type, config, children) {
  //...
  // 這部分代碼就是我們一開始講的props的children字段棘劣,-2的原因是減去type,config楞遏,也就是后面剩下的children的長(zhǎng)度
  var childrenLength = arguments.length - 2;
//如果長(zhǎng)度是1茬暇,也就相當(dāng)于<Hello>這里是hello</Hello>只有“這里是hello”子節(jié)點(diǎn)首昔,此時(shí)我們就把該節(jié)點(diǎn)直接復(fù)給props.children
  if (childrenLength === 1) {
    props.children = children;
//如果長(zhǎng)度>1,也就相當(dāng)<Hello><div>這里是hello</div><div>這里是world</div></Hello>,這時(shí)我們要把兩個(gè)div合并到一個(gè)數(shù)組,然后復(fù)給props.children 可以看console.log打印糙俗,同理如果div當(dāng)中還嵌套div的話勒奇,便是一個(gè)遞歸的過(guò)程,
  } else if (childrenLength > 1) {
    var childArray = Array(childrenLength);
    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }
 //...最后這里返回的是ReactElement
  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
};

//ReactElement
var ReactElement = function (type, key, ref, self, source, owner, props) {
//...看到這里的屬性巧骚,我們發(fā)現(xiàn)似曾相識(shí)的吧赊颠,沒錯(cuò)就是console口打印出來(lái)的屬性
  var element = {
    type: type,
    key: key,
    ref: ref,
    props: props,
  };
//...
  return element;
};
image.png
image.png

總結(jié)

//到這里我們可以對(duì)這段代碼做個(gè)總結(jié)了
/*
1.class Hello extends React.Component
Hello繼承了React.Component類,而Component為React的一個(gè)屬性劈彪,調(diào)用的是ReactComponent函數(shù)竣蹦,而該函數(shù)的原型上面有一個(gè)setState函數(shù)
2.render 方法其實(shí)是調(diào)用的React.createElement函數(shù),而在這個(gè)函數(shù)中實(shí)現(xiàn)了屬性初始化以及Chidren復(fù)值給props.children的過(guò)程
*/
  class Hello extends React.Component{
            render(){
                return(
                    <div>
                        hello world
                    </div>
                )
            }
        }

到這里我們還沒有進(jìn)行掛載的哈,也就是我們還沒有得到react組件<Hello/>沧奴,只是做了組件聲明與初始化的講解痘括。

下一篇:react源碼解析(組件的掛載)
http://www.reibang.com/p/5e7c0eeef2e4

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市滔吠,隨后出現(xiàn)的幾起案子纲菌,更是在濱河造成了極大的恐慌,老刑警劉巖疮绷,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驰后,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡矗愧,警方通過(guò)查閱死者的電腦和手機(jī)灶芝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)唉韭,“玉大人夜涕,你說(shuō)我怎么就攤上這事∈舴撸” “怎么了女器?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)住诸。 經(jīng)常有香客問我驾胆,道長(zhǎng),這世上最難降的妖魔是什么贱呐? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任丧诺,我火速辦了婚禮,結(jié)果婚禮上奄薇,老公的妹妹穿的比我還像新娘驳阎。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布呵晚。 她就那樣靜靜地躺著蜘腌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饵隙。 梳的紋絲不亂的頭發(fā)上撮珠,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音金矛,去河邊找鬼芯急。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绷柒,可吹牛的內(nèi)容都是我干的志于。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼废睦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伺绽!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起嗜湃,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤奈应,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后购披,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杖挣,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年刚陡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惩妇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筐乳,死狀恐怖歌殃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蝙云,我是刑警寧澤氓皱,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站勃刨,受9級(jí)特大地震影響波材,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜身隐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一廷区、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抡医,春花似錦躲因、人聲如沸早敬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至水孩,卻和暖如春镰矿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俘种。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工秤标, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宙刘。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓苍姜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親悬包。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衙猪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容