<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é)果截圖
通過(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的文件
可以看到react的對(duì)象中有一個(gè)Componenet:ReactComponent屬性緊接著我們?nèi)タ匆幌翿eactComponent
可以看出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;
};
總結(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