本文爲學習react中的記錄。html
props
或state
有變化,執行render函數。React v16.7.0-alpha(內測) 將引入 Hooks, 這將意味着函數式組件將擁有相似類組件的特性。react
函數式組件,有時也被稱爲無狀態組件,沒有任何生命週期方法,意味着每次上層組件樹狀態發生變動時它們都會從新渲染,這就是由於缺乏 shouldComponentUpdate
方法致使的。這也一樣意味着您不能定義某些基於組件掛載和卸載的行爲。git
更有趣的是您在函數式組件中既不能使用 this
關鍵字或訪問到 ref
。對於習慣了嚴格意義上的類或面向對象風格的人來講,這很讓他們驚訝。這也是使用函數最大的爭論點。 另外一個有趣的事實就是您仍然能夠訪問到 context,若是您將 context 定義爲函數的一個 props。github
在編寫無狀態函數式組件時,您須要避免某些特定的模式。避免在函數式組件中定義函數,這是由於每一次函數式組件被調用的時候,一個新的函數都會被建立。算法
const Functional = ({...}) => {
const handleSomething = e => path(['event', 'target'], e)
return (
// ...
)
}
複製代碼
這個問題很容易解決,您能夠將這個函數做爲 props 傳遞進去,或者將它定義在組件外面。redux
const handleSomething = e => path(['event', 'target'], e)
const Functional = ({...}) => // ...
複製代碼
生命週期演示數組
在組件初始化階段會執行瀏覽器
- constructor
- static getDerivedStateFromProps()
- componentWillMount() / UNSAFE_componentWillMount()
- render()
- componentDidMount()
props
或state
的改變可能會引發組件的更新,組件從新渲染的過程當中會調用如下方法:緩存
- componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- componentWillUpdate() / UNSAFE_componentWillUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
- componentWillUnmount()
- componentDidCatch()
react組件的構造函數在掛載以前被調用。在實現React.Component
構造函數時,須要先在添加其餘內容前,調用super(props)
,用來將父組件傳來的props
綁定到這個類中,使用this.props
將會獲得。服務器
官方建議不要在constructor
引入任何具備反作用和訂閱功能的代碼,這些應當在componentDidMount()
中寫入。
constructor
中應當作些初始化的動做,如:初始化state
,將事件處理函數綁定到類實例上,但也不要使用setState()
。若是沒有必要初始化state或綁定方法,則不須要構造constructor
,或者把這個組件換成純函數寫法。
固然也能夠利用props
初始化state
,在以後修改state
不會對props形成任何修改,但仍然建議你們提高狀態到父組件中,或使用redux
統一進行狀態管理。
constructor(props) {
super(props);
this.state = {
color: props.initialColor
};
}
複製代碼
getDerivedStateFromProps
在組件實例化後,和接受新的props
後被調用。他返回一個對象來更新狀態,或者返回null表示新的props不須要任何state的更新。
若是是因爲父組件的props更改,所帶來的從新渲染,也會觸發此方法。
調用steState()
不會觸發getDerivedStateFromProps()
。
componentWillMount()
將在react將來版本中被棄用。UNSAFE_componentWillMount()
在組件掛載前被調用,在這個方法中調用setState()
不會起做用,是因爲他在render()
前被調用。
爲了不反作用和其餘的訂閱,官方都建議使用componentDidMount()
代替。這個方法是用於在服務器渲染上的惟一方法。
render()
方法是必需的。當他被調用時,他將計算this.props
和this.state
,並返回如下一種類型:
null
,什麼也不渲染當返回null
,false
,ReactDOM.findDOMNode(this)
將會返回null,什麼都不會渲染。
render()
方法必須是一個純函數,他不該該改變state
,也不能直接和瀏覽器進行交互,應該將事件放在其餘生命週期函數中。 若是shouldComponentUpdate()
返回false
,render()
不會被調用。
你也能夠在render()
中使用數組,如:(不要忘記給每一個數組元素添加key,防止出現警告)
render() {
return [
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
複製代碼
換一種寫法,能夠不寫key(v16++)
render() {
return (
<React.Fragment> <li>First item</li> <li>Second item</li> <li>Third item</li> </React.Fragment> ); } 複製代碼
官方示例:
function Clock(props) {
return (
<div> <h1>Hello, world!</h1> <h2>It is {props.date.toLocaleTimeString()}.</h2> </div>
);
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />, document.getElementById('root') ); } setInterval(tick, 1000); 複製代碼
官方建議使用getDerivedStateFromProps
函數代替componentWillReceiveProps()
。當組件掛載後,接收到新的props
後會被調用。若是須要更新state
來響應props
的更改,則能夠進行this.props
和nextProps
的比較,並在此方法中使用this.setState()
。
若是父組件會讓這個組件從新渲染,即便props
沒有改變,也會調用這個方法。
react不會在組件初始化props時調用這個方法。調用this.setState
也不會觸發。
調用shouldComponentUpdate
使react知道,組件的輸出是否受state
和props
的影響。默認每一個狀態的更改都會從新渲染,大多數狀況下應該保持這個默認行爲。
在渲染新的props
或state
前,shouldComponentUpdate
會被調用。默認爲true
。這個方法不會在初始化時被調用,也不會在forceUpdate()
時被調用。返回false
不會阻止子組件在state
更改時從新渲染。
若是shouldComponentUpdate()
返回false
,componentwillupdate
,render
和componentDidUpdate
不會被調用。
在將來版本,shouldComponentUpdate()將會做爲一個提示而不是嚴格的指令,返回false仍然可能致使組件的從新渲染。 官方並不建議在
shouldComponentUpdate()
中進行深度查詢或使用JSON.stringify()
,他效率很是低,而且損傷性能。
在渲染新的state
或props
時,UNSAFE_componentWillUpdate
會被調用,將此做爲在更新發生以前進行準備的機會。這個方法不會在初始化時被調用。
不能在這裏使用this.setState(),也不能作會觸發視圖更新的操做。若是須要更新state
或props
,調用getDerivedStateFromProps
。
在react render()
後的輸出被渲染到DOM以前被調用。它使您的組件可以在它們被潛在更改以前捕獲當前值(如滾動位置)。這個生命週期返回的任何值都將做爲參數傳遞給componentDidUpdate()。
在更新發生後當即調用componentDidUpdate()
。此方法不用於初始渲染。當組件更新時,將此做爲一個機會來操做DOM。只要您將當前的props與之前的props進行比較(例如,若是props沒有改變,則可能不須要網絡請求),這也是作網絡請求的好地方。
若是組件實現getSnapshotBeforeUpdate()
生命週期,則它返回的值將做爲第三個「快照」參數傳遞給componentDidUpdate()
。不然,這個參數是undefined
。
在組件被卸載並銷燬以前當即被調用。在此方法中執行任何須要的清理,例如使定時器無效,取消網絡請求或清理在componentDidMount()中建立的任何監聽。
錯誤邊界是React組件,能夠在其子組件樹中的任何位置捕獲JavaScript錯誤,記錄這些錯誤並顯示回退UI,而不是崩潰的組件樹。錯誤邊界在渲染期間,生命週期方法以及整個樹下的構造函數中捕獲錯誤。
若是類組件定義了今生命週期方法,則它將成爲錯誤邊界。在它中調用setState()
可讓你在下面的樹中捕獲未處理的JavaScript錯誤,並顯示一個後備UI。只能使用錯誤邊界從意外異常中恢復;不要試圖將它們用於控制流程。詳細
錯誤邊界只會捕獲樹中下面組件中的錯誤。錯誤邊界自己不能捕獲錯誤。
虛擬dom至關於在js和真實dom中間加了一個緩存,利用dom diff算法避免了沒有必要的dom操做,從而提升性能。
具體實現步驟以下:
用 JavaScript 對象結構表示 DOM 樹的結構;而後用這個樹構建一個真正的 DOM 樹,插到文檔當中
當狀態變動的時候,從新構造一棵新的對象樹。而後用新的樹和舊的樹進行比較,記錄兩棵樹差別把2所記錄的差別應用到步驟1所構建的真正的DOM樹上,視圖就更新了。