- React是一個專注提供清晰瞒津、簡潔赵誓、靈活的View層解決方案的庫
- 特點(diǎn):輕
- 組件化的開發(fā)思路
React組件
- React組件的構(gòu)建方式
- 用
React.createClass
構(gòu)建組件是 React 最傳統(tǒng)、也是兼容性最好的方法姥宝。
const Button = React.createClass({
getDefaultProps() {
return {
color: 'blue',
text: 'OK',
};
},
render() {
const { color, text } = this.props;
return (
<button className={`btn btn-${color}`}>
<em>{text}</em>
</button>
);
}
});
- 用ES6 標(biāo)準(zhǔn)的類語法的方式來構(gòu)建匕争。官方推薦。
class Greeting extends React.Component {
static defaultProps = {
name: 'World',
};
static propTypes = {
name: React.PropTypes.string.isRequired,
};
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
- 使用無狀態(tài)函數(shù)構(gòu)建
function Button({ color = 'blue', text = 'OK' }) {
return (
<button className={`btn btn-${color}`}>
<em>{text}</em>
</button>
);
}
組件本身即上面兩種 React 組件構(gòu)建方法中的 render 方法榔至。
- 組件內(nèi)的屬性和狀態(tài)
props
我們可以通過this.props.xx的形式獲取組件對象的屬性耗绿,對象的屬性可以任意定義杨箭,但要避免與JavaScript關(guān)鍵字沖突膝蜈。
組件可以定義初始值,自己不可更改props屬性值吕粗,只允許從父組件中傳遞過來:
// 父組件
class ParentComponent extends React.Component{
render(){
return(<Child name="name">);
}
}
// 子組件
class Child extends React.Component{
render(){
return(<Text>{this.props.name}</Text>);
}
}
父組件向子組件傳遞name="name"的props屬性纺荧,在子組件中使用this.props.name引用此屬性。
屬性類型prop type和默認(rèn)屬性 default prop可以通過類中的 static來聲明:
class Demo extends React.Component {
// 默認(rèn)props
static defaultProps = {
autoPlay: false,
maxLoops: 10,
}
// propTypes用于驗(yàn)證轉(zhuǎn)入的props
static propTypes = {
autoPlay: React.PropTypes.bool.isRequired,
maxLoops: React.PropTypes.number.isRequired,
posterFrameSrc: React.PropTypes.string.isRequired,
}
state = {
loopsRemaining: this.props.maxLoops,
}
}
- 遍歷對象的屬性
this.props.children會返回組件對象的所有屬性颅筋。
React 提供一個工具方法 React.Children 來處理 this.props.children 宙暇。我們可以用 React.Children.map或React.Children.forEach 來遍歷子節(jié)點(diǎn)。
var NotesList = React.createClass({
render: function() {
return (
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.body
);
state
組件用來改變自己狀態(tài)的屬性议泵,通常使用setState({key:value})來改變屬性值觸發(fā)界面刷新占贫,不能使用this.state.xxx來直接改變。 典型的場景是在接收到服務(wù)器返回的新數(shù)據(jù)先口,或者在用戶輸入數(shù)據(jù)之后靶剑。
對于經(jīng)常改變的數(shù)據(jù)且需要刷新界面顯示,可以使用state池充。
對于不需要改變的屬性值可以使用props。
React數(shù)據(jù)流
在 React 中缎讼,數(shù)據(jù)是自頂向下單向流動的收夸,即從父組件到子組件。
- props是由父組件傳遞給子組件的血崭。
- state是子組件內(nèi)部的維護(hù)的數(shù)據(jù)卧惜。
Virtual Dom
React 最大的特色是當(dāng)View層在渲染的時(shí)候,它不會直接從模板里面去構(gòu)建一個DOM節(jié)點(diǎn). 首先, 它創(chuàng)建一些暫時(shí)的, 虛擬的 DOM, 然后和真實(shí)的DOM還有創(chuàng)建的Diffs一起做對比, 然后才決定需不需要渲染。
- JSX
- diff算法
React生命周期
生命周期:廣義上 => 各種客觀事物的階段性變化及其規(guī)律夹纫。生命體的周期是單一咽瓷,不可逆,而軟件開發(fā)的生命周期會根據(jù)方法的不同在完成前重新開始舰讹。
React 組件的生命周期可以分為掛載(Mounting)茅姜、渲染(Updating)和卸載(Unmounting)這幾個階段。
當(dāng)渲染后的組件需要更新時(shí)月匣,重新去渲染組件钻洒,直至卸載。
- Mounting:初始化階段(已插入真實(shí) DOM)
初始化階段可以使用的函數(shù):
getDefaultProps
: 只調(diào)用一次锄开,實(shí)例之間共享引用
getInitialState
: 初始化每個實(shí)例特有的狀態(tài)
componentWillMount
: render之前最后一次修改狀態(tài)的機(jī)會素标。如果在這個方法內(nèi)調(diào)用setState,render()將會感知到更新后的state,將會執(zhí)行僅一次萍悴,盡管state改變了头遭。
render
: 只能訪問this.props和this.state寓免,只有一個頂層組件,不允許修改狀態(tài)和DOM輸出
componentDidMount
: 成功render并渲染完成真實(shí)DOM之后觸發(fā)计维,可以修改DOM
調(diào)用順序
當(dāng)組件在客戶端被實(shí)例化袜香,第一次被創(chuàng)建時(shí),以下方法依次被調(diào)用:
getInitialState
componentWillMount
render
componentDidMount
- Updating :更新
componentWillReceiveProps(object nextProps)
在組件接收到新的 props 的時(shí)候調(diào)用享潜。在初始化渲染的時(shí)候困鸥,該方法不會調(diào)用。
用此函數(shù)可以作為 react 在 prop 傳入之后剑按, render() 渲染之前更新 state 的機(jī)會疾就。老的 props 可以通過 this.props 獲取到。在該函數(shù)中調(diào)用 this.setState() 將不會引起第二次渲染艺蝴。
shouldComponentUpdate(object nextProps, object nextState)
: 在接收到新的 props 或者 state猬腰,將要渲染之前調(diào)用。
該方法在初始化渲染的時(shí)候不會調(diào)用猜敢,在使用 forceUpdate 方法的時(shí)候也不會姑荷。如果確定新的 props 和 state 不會導(dǎo)致組件更新,則此處應(yīng)該 返回 false缩擂。
心得:重寫此方法你可以根據(jù)實(shí)際情況鼠冕,來靈活的控制組件當(dāng) props 和 state 發(fā)生變化時(shí)是否要重新渲染組件,也是優(yōu)化性能的一項(xiàng)手段胯盯。
componentWillUpdate(object nextProps, object nextState)
:在接收到新的 props 或者 state 之前立刻調(diào)用懈费。
在初始化渲染的時(shí)候該方法不會被調(diào)用。使用該方法做一些更新之前的準(zhǔn)備工作博脑。
注意:你不能在該方法中使用 this.setState()憎乙。如果需要更新 state 來響應(yīng)某個 prop 的改變,請使用 componentWillReceiveProps叉趣。
componentDidUpdate(object prevProps, object prevState)
: 在組件的更新已經(jīng)同步到 DOM 中之后立刻被調(diào)用泞边。
該方法不會在初始化渲染的時(shí)候調(diào)用。使用該方法可以在組件更新之后操作 DOM 元素疗杉。 - Unmounting:移除
componentWillUnmount
:在組件從 DOM 中移除的時(shí)候立刻被調(diào)用阵谚。
在該方法中執(zhí)行任何必要的清理,比如無效的定時(shí)器烟具,或者清除在componentDidMount 中創(chuàng)建的 DOM 元素椭蹄。
Redux
react-redux
庫提供了一個組件和一個 API 幫助 Redux
和 React
進(jìn)行綁定,
一個是 React 組件 <Provider/> 净赴,一個是 connect()绳矩。
<Provider/> 接受一個 store 作為props,它是整個 Redux 應(yīng)用的頂層組件玖翅,
connect() 提供了在整個 React 應(yīng)用的任意組件中獲取 store 中數(shù)據(jù)的功能翼馆。
它們一個將組件與redux關(guān)聯(lián)起來割以,一個將store傳給組件。組件通過dispatch發(fā)出action应媚,store根據(jù)action的type屬性調(diào)用對應(yīng)的reducer并傳入state和這個action严沥,reducer對state進(jìn)行處理并返回一個新的state放入store,connect監(jiān)聽到store發(fā)生變化中姜,調(diào)用setState更新組件消玄。
流程:
一、Provider組件接受redux的store作為props丢胚,然后通過context往下傳翩瓜。
二、connect函數(shù)收到Provider傳出的store携龟,然后接受三個參數(shù)mapStateToProps兔跌,mapDispatchToProps和組件,并將state和actionCreator以props傳入組件峡蟋,這時(shí)組件就可以調(diào)用actionCreator函數(shù)來觸發(fā)reducer函數(shù)返回新的state坟桅,connect監(jiān)聽到state變化調(diào)用setState更新組件并將新的state傳入組件。
connect(state => state, action)(Component);