地址:https://github.com/nanhupatar...
關注咱們團隊:react
Keys 是 React 用於追蹤哪些列表中元素被修改、被添加或者被移除的輔助標識。git
render () { return ( <ul> {this.state.todoItems.map(({item, key}) => { return <li key={key}>{item}</li> })} </ul> ) }
在開發過程當中,咱們須要保證某個元素的 key 在其同級元素中具備惟一性。在 React Diff 算法中 React 會藉助元素的 Key 值來判斷該元素是新近建立的仍是被移動而來的元素,從而減小沒必要要的元素重渲染。此外,React 還須要藉助 Key 值來判斷元素與本地狀態的關聯關係,所以咱們毫不可忽視轉換函數中 Key 的重要性。github
在代碼中調用 setState 函數以後,React 會將傳入的參數對象與組件當前的狀態合併,而後觸發所謂的調和過程(Reconciliation)。通過調和過程,React 會以相對高效的方式根據新的狀態構建 React 元素樹而且着手從新渲染整個 UI 界面。在 React 獲得元素樹以後,React 會自動計算出新的樹與老樹的節點差別,而後根據差別對界面進行最小化重渲染。在差別計算算法中,React 可以相對精確地知道哪些位置發生了改變以及應該如何改變,這就保證了按需更新,而不是所有從新渲染。算法
初始化階段:redux
運行中狀態:promise
銷燬階段:瀏覽器
shouldComponentUpdate 這個方法用來判斷是否須要調用 render 方法從新描繪 dom。由於 dom 的描繪很是消耗性能,若是咱們能在 shouldComponentUpdate 方法中可以寫出更優化的 dom diff 算法,能夠極大的提升性能。緩存
參考react 性能優化-sf安全
虛擬 dom 至關於在 js 和真實 dom 中間加了一個緩存,利用 dom diff 算法避免了沒有必要的 dom 操做,從而提升性能。性能優化
用 JavaScript 對象結構表示 DOM 樹的結構;而後用這個樹構建一個真正的 DOM 樹,插到文檔當中當狀態變動的時候,從新構造一棵新的對象樹。而後用新的樹和舊的樹進行比較,記錄兩棵樹差別把 2 所記錄的差別應用到步驟 1 所構建的真正的 DOM 樹上,視圖就更新了。
Refs 是 React 提供給咱們的安全訪問 DOM 元素或者某個組件實例的句柄。咱們能夠爲元素添加 ref 屬性而後在回調函數中接受該元素在 DOM 樹中的句柄,該值會做爲回調函數的第一個參數返回:
class CustomForm extends Component { handleSubmit = () => { console.log("Input Value: ", this.input.value) } render () { return ( <form onSubmit={this.handleSubmit}> <input type='text' ref={(input) => this.input = input} /> <button type='submit'>Submit</button> </form> ) } }
上述代碼中的 input 域包含了一個 ref 屬性,該屬性聲明的回調函數會接收 input 對應的 DOM 元素,咱們將其綁定到 this 指針以便在其餘的類函數中使用。另外值得一提的是,refs 並非類組件的專屬,函數式組件一樣可以利用閉包暫存其值:
function CustomForm ({handleSubmit}) { let inputElement return ( <form onSubmit={() => handleSubmit(inputElement.value)}> <input type='text' ref={(input) => inputElement = input} /> <button type='submit'>Submit</button> </form> ) }
<Twitter username='tylermcginnis33'> {(user) => user === null ? <Loading /> : <Badge info={user} />} </Twitter>
import React, { Component, PropTypes } from 'react' import fetchUser from 'twitter' // fetchUser take in a username returns a promise // which will resolve with that username's data. class Twitter extends Component { // finish this }
若是你還不熟悉回調渲染模式(Render Callback Pattern),這個代碼可能看起來有點怪。這種模式中,組件會接收某個函數做爲其子組件,而後在渲染函數中以 props.children 進行調用:
import React, { Component, PropTypes } from 'react' import fetchUser from 'twitter' class Twitter extends Component { state = { user: null, } static propTypes = { username: PropTypes.string.isRequired, } componentDidMount () { fetchUser(this.props.username) .then((user) => this.setState({user})) } render () { return this.props.children(this.state.user) } }
這種模式的優點在於將父組件與子組件解耦和,父組件能夠直接訪問子組件的內部狀態而不須要再經過 Props 傳遞,這樣父組件可以更爲方便地控制子組件展現的 UI 界面。譬如產品經理讓咱們將本來展現的 Badge 替換爲 Profile,咱們能夠輕易地修改下回調函數便可:
<Twitter username='tylermcginnis33'> {(user) => user === null ? <Loading /> : <Profile info={user} />} </Twitter>
在 HTML 中,相似 <input>
, <textarea>
和 <select>
這樣的表單元素會維護自身的狀態,並基於用戶的輸入來更新。當用戶提交表單時,前面提到的元素的值將隨表單一塊兒被髮送。但在 React 中會有些不一樣,包含表單元素的組件將會在 state 中追蹤輸入的值,而且每次調用回調函數時,如 onChange 會更新 state,從新渲染組件。一個輸入表單元素,它的值經過 React 的這種方式來控制,這樣的元素就被稱爲"受控元素"。
高階組件是一個以組件爲參數並返回一個新組件的函數。HOC 運行你重用代碼、邏輯和引導抽象。最多見的多是 Redux 的 connect 函數。除了簡單分享工具庫和簡單的組合,HOC 最好的方式是共享 React 組件之間的行爲。若是你發現你在不一樣的地方寫了大量代碼來作同一件事時,就應該考慮將代碼重構爲可重用的 HOC。
由於 this.props 和 this.state 的更新多是異步的,不能依賴它們的值去計算下一個 state。
你可使用屬性初始值設定項(property initializers)來正確綁定回調,create-react-app 也是默認支持的。在回調中你可使用箭頭函數,但問題是每次組件渲染時都會建立一個新的回調。
在 super() 被調用以前,子類是不能使用 this 的,在 ES2015 中,子類必須在 constructor 中調用 super()。傳遞 props 給 super() 的緣由則是便於(在子類中)能在 constructor 訪問 this.props。
在 React 組件中,應該在 componentDidMount 中發起網絡請求。這個方法會在組件第一次「掛載」(被添加到 DOM)時執行,在組件的生命週期中僅會執行一次。更重要的是,你不能保證在組件掛載以前 Ajax 請求已經完成,若是是這樣,也就意味着你將嘗試在一個未掛載的組件上調用 setState,這將不起做用。在 componentDidMount 中發起網絡請求將保證這有一個組件能夠更新了。
爲了解決跨瀏覽器兼容性問題,您的 React 中的事件處理程序將傳遞 SyntheticEvent 的實例,它是 React 的瀏覽器本機事件的跨瀏覽器包裝器。
這些 SyntheticEvent 與您習慣的原生事件具備相同的接口,除了它們在全部瀏覽器中都兼容。有趣的是,React 實際上並無將事件附加到子節點自己。React 將使用單個事件監聽器監聽頂層的全部事件。這對於性能是有好處的,這也意味着在更新 DOM 時,React 不須要擔憂跟蹤事件監聽器。
React.createElement():JSX 語法就是用 React.createElement()來構建 React 元素的。它接受三個參數,第一個參數能夠是一個標籤名。如 div、span,或者 React 組件。第二個參數爲傳入的屬性。第三個以及以後的參數,皆做爲組件的子組件。
React.createElement( type, [props], [...children] )
React.cloneElement()與 React.createElement()類似,不一樣的是它傳入的第一個參數是一個 React 元素,而不是標籤名或組件。新添加的屬性會併入原有的屬性,傳入到返回的新元素中,而就的子元素獎盃替換。
React.cloneElement( element, [props], [...children] )
React.createClass()、ES6 class 和無狀態函數。
Flux 的最大特色,就是數據的"單向流動"。
creat-react-app Yeoman 等