① 函數式定義的無狀態組件(Stateless Functional)javascript
性能更高效、代碼更簡潔
沒有 state,也就是無狀態
不須要管理/維護 組件的生命週期
純函數,相同的 props 會獲得一樣的UI渲染結果
組件不會被實例化,總體渲染性能獲得提高
組件不能訪問this對象java
②.
ES5原生方式React.createClass定義的組件
是react剛開始推薦的建立組件的方式,這是ES5的原生的JavaScript來實現的React組件
是建立有狀態的組件
些組件是要被實例化的,而且能夠訪問組件的生命週期方法
建立的組件,其每個成員函數的this都有React自動綁定react
③.ES6 方式定義的組件(Class Components)
ES6的形式來建立react的組件的,是React目前極爲推薦的建立有狀態組件的方式
建立的組件,其成員函數不會自動綁定this,須要開發者手動綁定,不然this不能獲取當前組件實例對象
有三種手動綁定方法:能夠在構造函數中完成綁定,也能夠在調用時使用method.bind(this)來完成綁定,還可使用arrow function來綁定算法
class App extends Component { constructor(props) { super(props) this.state = { value: 'hi' } } onInputChange = (e) => { this.setState({ value: e.target.value }) } render() { const { value } = this.state return ( <input value={value} onChange={this.onInputChange} /> ) } }
文本描述
1.初始化state設置表單的默認值,例如 this.state = { value: 'hi' }
2.每當表單值發生變化時,調用onChange事件
3.經過對象e拿到改變的狀態,例如e.target.value
4.經過setState更新應用value 並 觸發視圖從新渲染,最終完成表單組件的更新redux
... this.state = { text : '這是一個栗子' } ... // 使用傳遞對象的寫法 handleClick = () => { this.setState({ text: this.state.text + '111' }) this.setState({ text: this.state.text + '222' }) } // 使用傳遞函數的寫法 handleClick = () => { this.setState((prevState) => { return { text: prevState.text + '111' } }) this.setState((prevState) => { return { text: prevState.text + '222' } }) } render() { return <div onClick={this.handleClick}>{this.state.text}</div> }
兩種傳遞方式,獲得的結果是不同的。less
傳遞對象 => this.state.text => '這是一個栗子222'
傳遞函數 => this.state.text => '這是一個栗子111222'函數
setState爲了提高性能,在批量執行 state 改變在作統一的DOM渲染。而在這個批量執行的過程當中,若是你屢次傳遞的是一堆對象,它就會作一些對象合併或者組合的操做,例如Object.assign({}, { a: '111' }, { a: '222' })。若是key值同樣的話,後面的值會覆蓋掉前面的值。
但屢次傳遞函數方式,每次 React 從 setState 執行函數,並經過傳遞已更新的狀態來更新你的狀態。這使得功能 setState 能夠基於先前狀態設置狀態。工具
render() { return ( <ul> list.map((item, index) => { return <li key={item.id}>{item.name} - {item.age}</li> }) </ul> ) }
5.keys 是 React 用於追蹤哪些列表中元素被修改、被添加或者被移除的輔助標識
之因此須要key,由於react 是很是高效的,它會藉助元素的 key 值來判斷該元素是新建立的,或者移動(交換位置)而來的,從而減小沒必要要的元素重渲染性能
這樣作的效率是很是很是很是低的,只有list變化了, 每一個元素對應的key都變了,react Virtual DOM就不論有沒有相同的項,更新都會從新渲染了。因此咱們要保證某個元素的 key 在其同級元素中具備惟一性, 這個key 的值能夠直接後臺數據返回的 idthis
2.子組件向父組件通訊
子組件向父組件傳遞數據(通訊) 也是要經過 props 傳遞一個函數,子組件調用這個函數,並將子組件須要傳遞的數據做爲參數,傳遞給父組件
3.兄弟組件之間通訊
能夠經過他們的共同父組件來實現,
在React中,也有一個render函數來將虛擬DOM樹,而且,React中有state轉移的過程,因此每次state有變化以後,就會觸發render函數,從新構造一個虛擬DOM樹。對比新舊虛擬DOM樹的差異,記錄下差別,而後只針對差別部分對應的真實DOM進行操做。
如何進行新舊虛擬DOM樹的對比呢?
這裏採用的是Diff算法。Diff算法比較複雜,主要的思路是這樣的。
首先,每一次生成的虛擬DOM樹上的各個節點都對應惟一的一個id,當第二次生成了新的DOM樹時,對原來樹上的每個節點對比新樹上對應節點,若是不一樣,就記錄下來這個差別。同時,差別也分爲不少種:
替換節點; 修改屬性; 對文本內容修改 移動、刪除、增長節點;
好比,替換節點就須要調原生JS的repaceChild()接口; 對於修改屬性,則要調setAttribute()接口等等。