2 回答

TA貢獻(xiàn)1111條經(jīng)驗(yàn) 獲得超0個(gè)贊
創(chuàng)建一個(gè) action,并且給一個(gè)標(biāo)識(shí),比如 isAPI = true 在 router 的 onEnter 中 dispatch 這個(gè) action 在 middleware 中根據(jù) action 的配置來(lái)發(fā)送 ajax 請(qǐng)求,next 的時(shí)候把 response 作為 payload 往后傳 在 reducer 中拿到 response

TA貢獻(xiàn)1856條經(jīng)驗(yàn) 獲得超5個(gè)贊
一個(gè)網(wǎng)站,從功能上劃分,都能整理出一個(gè)個(gè)細(xì)小的組件,比如一個(gè)頭部,一個(gè)按鈕,一個(gè)banner,那么怎樣才能寫(xiě)好一個(gè)可以在多個(gè)頁(yè)面共享數(shù)據(jù)或私有狀態(tài)的組件呢?
以一個(gè)移動(dòng)端常見(jiàn)的header頭部為例,左邊是返回按鈕,有的還帶有文字,中間是標(biāo)題文字,右邊可能有圖片或者文字。
<div>
<i>返回按鈕</i>
<span>標(biāo)題</span>
<img src="" />
</div>
返回按鈕
返回文字(backText)
標(biāo)題(title)
圖片或文字(icon)
返回點(diǎn)擊事件
圖片或文字點(diǎn)擊事件(handleClick)
背景樣式
文字樣式
這8個(gè)基本因素是所有頭部都共用的,有的可有,有的可無(wú),為了保證每個(gè)網(wǎng)頁(yè)都能調(diào)用同一個(gè)頭部組件,又要確保文本和事件還有樣式可以自定義。將可變的因素提取出來(lái),通過(guò)變量的方式傳入組件。
在react中,傳遞變量用this.props。
const {backText, title, icon, handleClick} = this.props
let _backText = backText || false,
_title = title || false,
_icon = icon || false
return (
<div>
<i onClick={handleClick}>{_backText}</i>
<span>{_title}</span>
<img src={_icon} />
</div>
)
在父容器里面調(diào)用header組件的用法和安卓上類(lèi)似,都是通過(guò)參數(shù)初始化配置。
handleClick(){
//注意,使用context的童鞋,需要定義contextType才可以,不然會(huì)報(bào)錯(cuò)
this.context.router.go(-1)
}
render() {
return (
<Header
backText="返回首頁(yè)"
title="個(gè)人中心"
icon={imgUrl}
handleClick={this.handleClick}
/>
)
}
static contextTypes = {
router: React.PropTypes.object.isRequired
};
通過(guò)簡(jiǎn)單的配置,就能構(gòu)造更多可復(fù)用的組件,組件拆的越細(xì),復(fù)用的程度就越高,這里沒(méi)有做傳入樣式的例子,但是樣式的初始化也是類(lèi)似的方法。
還有常用的組件,如彈框:
<div>
<p>標(biāo)題</p>
<p>中間內(nèi)容,可以是text或者帶有多個(gè)標(biāo)簽樣式的text</p>
<p>
<a>左邊按鈕,通常叫做取消</a>
<a>右邊按鈕,通常叫做確認(rèn)</a>
</p>
</div>
跟header組件實(shí)現(xiàn)一樣,首先把可變的數(shù)據(jù)部分和事件抽象出來(lái)。
標(biāo)題(title)
中間內(nèi)容(content)
左邊按鈕文本(leftText)
右邊按鈕文本(rightText)
左邊按鈕的點(diǎn)擊事件(leftClick)
右邊按鈕的點(diǎn)擊事件(rightClick)
render() {
const {title, content, leftText, rightText, leftClick, rightClick} = this.props
//這里再做一次判斷空數(shù)據(jù)或者為定義數(shù)據(jù)的處理,沒(méi)人能保證傳遞進(jìn)來(lái)的參數(shù)一定存在或者一定不為空。
return (
<div>
<div>{title}</div>
<div>{content}</div>
<div>
<a onClick={leftClick}>{leftText}</a>
<a onClick={rightClick}>{rightText}</a>
</div>
</div>
)
}
父容器組件調(diào)用彈框組件
leftClick() {
//左邊按鈕事件
}
rightClick() {
//右邊按鈕事件
}
render() {
const content = <p><span>提示語(yǔ)1</span><span>提示語(yǔ)2</span></p>
return (
<BombBox
title="彈框標(biāo)題"
content={content}
leftText="取消"
rightText="確認(rèn)"
leftClick={this.leftClick}
rightClick={this.rightClick}
/>
)
}
到這里就結(jié)束了嗎?不是的,我們知道,還有一個(gè)東西叫做state,react中,控制彈框的出現(xiàn)和消失,通過(guò)state來(lái)控制,而我這里要講的是react和redux結(jié)合使用,發(fā)送一個(gè)dispacth action改變state的狀態(tài),使得彈框出現(xiàn)和隱藏。
leftClick() {
//左邊按鈕事件,隱藏彈框,調(diào)用一個(gè)action函數(shù),該action函數(shù)會(huì)改變r(jià)educer中state的狀態(tài)
this.props.BombAction(false)
}
rightClick() {
//右邊按鈕事件,點(diǎn)擊跳轉(zhuǎn)到下一個(gè)頁(yè)面的路由
this.context.router.push(`/nextRoute`)
//這里還需要做一件事,點(diǎn)擊確定后,首先要清除掉彈出框的true狀態(tài),恢復(fù)成false,避免在其他頁(yè)面共用該組件的彈出框還沒(méi)點(diǎn)擊出發(fā)事件就已經(jīng)彈出來(lái)了。這一步也可以在BombBox組件內(nèi)部用componentWillUnmount()來(lái)觸發(fā)。
this.props.BombAction(false)
}
render() {
const content = <p><span>提示語(yǔ)1</span><span>提示語(yǔ)2</span></p>
//在叫做global(全局)的reducer定義1個(gè)state參數(shù)BombStatus,表示彈框的狀態(tài),true為顯示彈框,false為隱藏彈框。默認(rèn)是false
const {BombStatus} = this.props.global
return (
<div>
{
BombStatus ?
<BombBox
title="彈框標(biāo)題"
content={content}
leftText="取消"
rightText="確認(rèn)"
leftClick={this.leftClick}
rightClick={this.rightClick}
/> : false
}
</div>
)
}
static contextTypes = {
router: React.PropTypes.object.isRequired
};
到這里,一個(gè)基本的可復(fù)用彈框組件就完成了,在任意一個(gè)頁(yè)面,調(diào)用該組件的方法都是一樣的,即發(fā)送一個(gè)action去改變state的狀態(tài),然后讓彈框組件加載進(jìn)來(lái)。隱藏也是改變state的狀態(tài)。
還有很多的例子,比如表格,li列表(常見(jiàn)在分頁(yè)組件上)等等。。。。
無(wú)論是一個(gè)簡(jiǎn)單的組件,還是一個(gè)復(fù)雜的組件,都要記住一點(diǎn),先抽象出來(lái)可變的內(nèi)容和事件,然后通過(guò)action去控制組件的state狀態(tài),不要在組件內(nèi)部去用setState和getState,前提是你也是用redux來(lái)管理state。
組件是個(gè)view,要保證組件的純凈,這樣服用的程度就會(huì)更高。
- 2 回答
- 0 關(guān)注
- 485 瀏覽
添加回答
舉報(bào)