? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?創(chuàng)建可重用的組建
為了創(chuàng)建真實(shí)可重用的組建铜涉,我們需要理解React自定義的組建和最好是選擇一個(gè)或另一個(gè)之間不同的可能性趟畏,最近椎瘟,一種新的組建類型被React提出阶淘,即聲明一個(gè)組建為無狀態(tài)的函數(shù)粤攒,掌握它栽渴,學(xué)會何時(shí)使用它和為什么要使用它尖坤,也越來越變的重要,
你可能已經(jīng)使用了組建的內(nèi)部狀態(tài)闲擦,但是或許你還不能清晰的使用它和它會帶來哪些問題慢味,
最好的學(xué)習(xí)方式是看例子,那么接下來墅冷,將會會用寫一個(gè)組建提供單一的目的并且轉(zhuǎn)化成可重用的一個(gè)組建纯路,
首先,讓我們退后一步繼續(xù)討論基本的概念寞忿,然后大步的創(chuàng)建生動(dòng)的組建樣式直到這章的最后驰唬,
在這個(gè)章節(jié)里:
-不同創(chuàng)建React組建的方式和如何選擇
-什么是無狀態(tài)組建,功能和狀態(tài)之間的不同
-狀態(tài)是如何運(yùn)行的,避免使用它
-定義清晰的Prop類型為每個(gè)組建為什么很重要叫编,怎樣產(chǎn)生動(dòng)態(tài)的文檔配合React Docgen
-一個(gè)真實(shí)的例子轉(zhuǎn)化耦合的組建成一個(gè)可重用的組建
-如何創(chuàng)建生動(dòng)的樣式從React storybook
創(chuàng)建類
我們已經(jīng)在第一章的時(shí)候辖佣,使用過elements顯示過組建,現(xiàn)在我們用另外一種方式定義組建
繼承自React.Component
推薦使用
主要的不同點(diǎn)
出去語法的差異搓逾,還有重要的不同卷谈,在使用的時(shí)候應(yīng)特別的注意,選擇最合適的
Props
createClass?
const Button = React.createClass({??
? ? ?propTypes: {? ??
? ? ? ? ? text: React.PropTypes.string,?
? ? ? },??
? ? ?getDefaultProps() {? ?
? ? ? ? ? ?return {? ? ? text: 'Click me!',? ? }??
? ? ?},??
? ? ?render() {? ??
? ? ? ? ? ? ?return{this.props.text}},?
})
如你所見恃逻,我們使用propTypes 屬性列出所有props傳遞給組建,然后使用getDefaultProps函數(shù)定義值藕施,
達(dá)到同樣目的用classes的寫法如下
class Button extends React.Component {??
? ? ? render() {? ??
? ? ? ? ? return{this.props.text}
? ? ? }?
}
Button.propTypes = {? text: React.PropTypes.string, }
Button.defaultProps = {? text: 'Click me!', }
state
const Button = React.createClass({?
? ? getInitialState() {? ??
? ? ? ? ? return {? ? ? text: 'Click me!',? ? }?
? ? },??
? ? render() { ?<button> ?return{this.state.text}}</button>},?
})
class Button extends React.Component {??
? ? ? constructor(props) {? ??
? ? ? ? ? super(props)
? ? ? ? ? this.state = {
? ? ? ? ? ? ? ?text: 'Click me!',? ?
? ? ? ? ? }??
? ? ? ?}??
? ? ?render() {? ? return{this.state.text}}
})
Autobinding
箭頭函數(shù) 解決事件綁定的一個(gè)方法是使用箭頭函數(shù)
() => this.setState() ?用babel轉(zhuǎn)化成
var _this = this;
(function () {? return _this.setState(); });
class Button extends React.Component {?
?handleClick() {? ? console.log(this)? }??
render() {? ? return <button onClick={()=>this.handleClick()}></button>}
}
這樣做不會有什么問題寇损,唯一的缺點(diǎn)是如果考慮性能的話還要理解代碼本身,其實(shí)裳食,箭頭函數(shù)的副作用,每一次render的時(shí)候如果遇到這些寫法矛市,都會重新用handleClick函數(shù)與this去綁定從而重新創(chuàng)建一個(gè)新的函數(shù),影響性能,
問題是诲祸,如果我們傳遞一個(gè)函數(shù)到子組建浊吏,子組建接受一個(gè)新的prop在每次更新的時(shí)候,導(dǎo)致無效的渲染救氯,這就是問題的出現(xiàn)找田,特別是如果組建是純的,最好的解決方式是綁定這個(gè)函數(shù)一次在組建的構(gòu)造函數(shù)里面着憨,
class Button extends React.Component {??
? ? ? ? constructor(props) {? ??
? ? ? ? ? ? ? ? ? super(props)? ?
? ? ? ? ? ? ? ? ? ?this.handleClick = this.handleClick.bind(this)??
? ? ? ?}?
? ? ? handleClick() {? ? console.log(this)? }?
? ? ? render() {? ? return <button onClick={this.handleClick}></button>} }
無狀態(tài)的組建
no state/lifecycle/refs/event handlers?