第一章(Raact數據流、React生命周期、React與DOM)
React數據流
在React中,數據是自項向下單向流動的。即從父組件到子組件。
- 如果頂層組件初始化props,那么React會向下遍歷整棵組件樹,重新嘗試渲染所有相關的子組件。而state只關心每個組件自己的內部的狀態,這些狀態只能在組件內改變。
state
- 當組件內部使用庫內置的setState方法時,最大的表現行為就是該組合會嘗試重新渲染。
import React,{Component} form 'react';
class Counter extends Component{
constructor(pros){
super(props);
this.state = {
count:0,
};
}
handleClick(e){
e.preventDefault();
this.setState({
count : this.state.count + 1,
});
}
render(){
renturn(
<div>
<p>{this.state.count}</p>
<a href="#" onClick={this.handleClick}>更新</a>
</div>
);
}
}
上述例子是通過點擊“更新”按鈕不斷的更新內部值。把組件內狀態封裝在現實中。
- setState 是一個異步方法。一個生命周期內所有的setState方法會合并操作。
props
- 是react用來讓組件之間相互聯系的一種機制。
- react的單向數據流,主要的流動管道是props。其本身不可變的,組件的props一定來自默認屬性或者通過父組件傳遞而來。
- 組件的部分props
- className:根節點的class。
- classPrefix:class的統一前綴。有助于對樣式與交互分離。
- defaultActiveIndex和activeIndex:默認的激活索引。
- onChange:回調函數。一般與activeIndex搭配使用。
- react為props提供了默認配置,可通過defaultProps靜態變量的方式定義。
static defaultProps ={
classPrefix:'',
onChange:()=>{},
};
- 子組件prop
- 在react中有一個重要且內置的prop——children,代表組件的子組件集合。
- React.Children是React官方提供的一系列操作children的方法。提供諸如map、forEach、count等實用函數。
- 組件props
- 用function prop與父組件通信
- 對于state,它的通信集中在組件內部。對于props,它的通信是父組件向子組件的傳播。
- propType
- 用于規范props的類型與必需的狀態。若組件定義了propType,那么在開發環境下,就會對組件的props值的類型作檢查。
React生命周期
react組件的生命周期分為掛載、渲染和卸載。
掛載或卸載過程
- 組件的掛載
- 主要做組件狀態的初始化
import React,{Component,PropTypes} form 'react'; class App extends Component{ static propTypes={ //... }; static defaultProps={ //... }; constructor(props){ super(props); this.state={ //... }; } componentWillMount(){ //... } componentDidMount(){ //... } render(){ return <div>This is a demo.</div>; } }
- 兩個生命周期方法
- componentWillMount,在render方法之前執行。(渲染前)
- componentDidMount,在render方法之后執行。(渲染后)
- 執行setState方法
- 在componentWillMount中,組件會更新state,但組件只渲染一次。無意義的執行
- 在componentDidMount中,組件會再次更新,在初始化過程中就渲染了兩次。
- 組件的卸載
- 只有componentWillMount這一個卸載前狀態。
數據更新過程
- 指的是父組件向下傳遞props或組件自身執行setState方法時發生的一系列更新動作。
import React,{Component,PropTypes} from 'react';
class App extends Component{
componentWillReceiveProps(nextProps){
//this.setState({})
}
shouldComponentUpdate(nextProps,nextState){
//...
}
componentWillUpdate(nextProps,nextState){
//...
}
componentDidUpdate(prevProps,prevState){
//...
}
render(){
return <div>This is a demo.</div>
}
}
- 組件自身的state更新,會依次執行shouldComponentUpdate、componentWillUpdate、rebder和componentDidUpdate。
- shouldComponentUpdate 接收需要更新的props和state。開發者加入必要的條件判斷,當方法返回false,組件不再向下執行生命周期方法。
- componentWillUpdate方法提供需要更新的props和state,代表更新過程中渲染前時刻;componentDidUpdate方法提供更新前的props和state,代表更新過程中渲染后時刻。
- 如果組件是由父組件更新props而更新的,那么在shouldComponentUpdate之前會先執行componentWillReceiveProps方法。在此方法中調用setState不會有二次渲染。
React與DOM
- 在組件開實現中,不會用到ReactDOM,只有在頂層組件以及由于React模型所限而不得不操作DOM的時候,才會用。
ReactDOM
- findDOMNode
- React提供的獲取DOM元素的方法。
DOMElement findDOMNode(ReactComponent component)
- 當組件被渲染到DOM中之后,findDOMNode返回該React組件實例相應的DOM節點。它可以用于獲取表單的value以及用于DOM的測量。
//當前組件加載完時獲取當前DOM import React,{Component} from 'react'; import ReactDOM from 'react-dom'; class App extends Component{ componentDidMount(){ //this為當前組件實例 const dom = ReactDOM.findDOMNode(this); } render(){} }
- findDOMNode只對已經掛載的組件有效。
- render
- 用于把React渲染的Virtual DOM渲染到瀏覽器的DOM當中。
ReactComponent render( ReactElement element, DOMElement container, [function callback] )
- 該方法把元素掛載到container中,并返回element實例(refs引用)。如果是無狀態組件,render會返回null,當組件裝載完畢時,callback就會被調用。
- 再次更新時,React不會把組件重新渲染,而是用DOM diff算法做局部更新。
ReactDOM的不穩定方法
- 有兩種不穩定方法
refs
- 組件中特殊的prop,可以附加到任何一個組件上。組件被調用時會指向一個實例,而refs會指向這個實例。
- 可以是一個回調函數,這個回調函數會在組件掛載之后立即執行。
- refs同樣支持字符串,對于DOM操作,不僅可以使用findDOMNode獲得該組件DOM,還可以使用refs獲得組件內部的DOM。
React之外的DOM操作
- React的 聲明式渲染機制把復雜的DOM操作抽象為簡單的state和props的操作,因此避免了很多直接的DOM操作。不過,仍有一些DOM操作是React無法避免的。