React的繪制思路
- React是用于構(gòu)建用戶界面的 JavaScript 庫。
- React每一幀都是通過虛擬DOM計(jì)算生成的。
- 有點(diǎn)像繪制動(dòng)畫。每畫一次,輸出的都是動(dòng)畫的一幀。render每運(yùn)行一次,返回的都是一副新的DOM地圖。
- 至于具體從虛擬DOM轉(zhuǎn)化為真正的DOM,這件事會(huì)由react-dom庫自行處理,不用考慮這部分的優(yōu)化問題。(涉及diff算法)
- React不負(fù)責(zé)數(shù)據(jù)的計(jì)算(簡單說,Vue中的computed/watcher/filter都需要自己寫了)
- React只有在主動(dòng)運(yùn)行render之后才會(huì)更新頁面。(所謂:可控。如果數(shù)據(jù)不合格,你可以不進(jìn)行此次更新)
React HelloWorld:http://js.jirengu.com/tocuv/edit?html,js

第一組是原生寫的,第二組是React,實(shí)現(xiàn)了點(diǎn)擊按鈕改變數(shù)字的功能。
作為一個(gè)先學(xué)Vue的小菜,我覺得這里為什么React不好學(xué)的原因。
比如說,想裝修房子:
jQuery的習(xí)慣是操家伙上,直接改,大不了再改回來;
Vue的習(xí)慣是拿原圖做標(biāo)注,圖上畫個(gè)紅圈說沙發(fā)搬走,它就搬走,不畫的地方不看;
React,是拿一個(gè)效果圖,不管原來長什么樣子,反正裝完了要跟我效果圖一致。。。
React每次進(jìn)行setState操作,都是當(dāng)前組件下一幀應(yīng)該展現(xiàn)出來的形態(tài),與前面的狀態(tài)無關(guān)。
React的組件
React每次繪制都是重新計(jì)算。對(duì)于想復(fù)用的組件,我們通常是寫一個(gè)構(gòu)造函數(shù)/類,通過這個(gè)函數(shù)構(gòu)造一個(gè)新對(duì)象,這個(gè)對(duì)象中會(huì)有自己的屬性。
現(xiàn)在的問題:如果每一個(gè)組件都用最簡單的function構(gòu)造,你會(huì)發(fā)現(xiàn),被嵌套進(jìn)去的組件是不會(huì)被重新render的。
在每一幀內(nèi),React是靜態(tài)的。

可以看到Box的render不會(huì)在點(diǎn)擊按鈕后運(yùn)行。
如果說React每次render是橫軸,那么指定組件就是縱軸。需要一個(gè)機(jī)制,將不相連的每一幀之間的規(guī)則串聯(lián)起來。

Vue是按縱軸寫,React是按橫軸寫
組件寫法:
React的function組件示例:http://js.jirengu.com/goyuv/edit?html,js,output
React的class組件示例:http://js.jirengu.com/zenah/31/edit?html,js,output
class Box extends React.Component{
// ---------- CONSTRUCTOR ---------- //
constructor(props){
super(props); // super關(guān)鍵字獲取屬性
this.state = {
number: 0
}
}
// ---------- FUNCTIONS ---------- //
add(){
// this.state.number+=1;
// 這里的this是undefined。。。
// 因?yàn)镽eact調(diào)用時(shí):onClick.call(undefined, args...);
// React強(qiáng)制將this改成了undefined?。。?
// 另外直接改this.state.XXX沒用。
this.setState({
number: this.state.number+1
})
}
sub(){
this.setState({
number: this.state.number-1
})
}
// ---------- RENDER ---------- //
render(){
return React.createElement("div", null,
React.createElement("span", null, this.state.number),
// onClick中是兩種解決this強(qiáng)制轉(zhuǎn)化為undefined問題的方法:
React.createElement("button", {onClick: this.add.bind(this)}, "+1"),
React.createElement("button", {onClick: ()=>this.sub()}, "-1")
)
}
}
// ---------- MAIN ---------- //
function render(){
ReactDOM.render(React.createElement(Box, null),document.getElementById("root"))
}
render();
- 關(guān)鍵字super用來繼承全部props;
- React調(diào)用組件內(nèi)方法時(shí):onClick.call(undefined, args...); 所以組件內(nèi)方法的this默認(rèn)為undefined。需要手動(dòng)重新綁定;
- setState默認(rèn)情況下會(huì)壓縮到一起進(jìn)行。此部分看代碼。