React如果在整個組件樹中傳遞數(shù)據(jù),需要在每一層傳遞屬性(單向數(shù)據(jù)流梅垄,從上往下傳遞),如果組件套的很深的話输玷,這樣傳遞就非常惡心了队丝。解決這個問題靡馁,除了Redux外,你還可以考慮使用強大的”context” API解決這個問題
1.什么時候該使用 Context
官方文檔:Context 旨在共享一個組件樹內(nèi)可被視為 “全局” 的數(shù)據(jù)机久,例如當前經(jīng)過身份驗證的用戶臭墨,主題或首選語言等。
2.具體用法
下面是一個簡單的上下文使用實例:最外層組件一個color,需要傳遞給Title組件和Content組件(根組件膘盖,繞過子組件胧弛,傳給孫組件),如下圖
基本組件結(jié)構(gòu)如下:
HomePage
class HomePage extends Component {
constructor(props) {
super(props);
this.state ={
color: 'red'
}
}
render() {
return (
<div>
<Header />
<Main />
</div>
)
}
}
Header和Main
class Header extends Component{
render() {
return (
<div>
<Title />
</div>
)
}
}
class Main extends Component{
render() {
return (
<div>
<Content />
</div>
)
}
}
Title和Content
class Title extends Component{
render() {
return (
<div>
這里是標題部分
</div>
)
}
}
class Content extends Component{
render() {
return (
<div>
這里是內(nèi)容部分
</div>
)
}
}
分一下幾步:
- 1:在父組件里定義childContextTypes---子上下文類型
static childContextTypes = {
color: PropTypes.string
}
- 2:在父組件里定義一個getChildContext用來返回上下文對象侠畔,返回的屬性要和第一步定義類型對應
getChildContext() {
return {
color: this.state.color
}
}
- 3:在這些要接收這些上下文對象的組件里定義contextTypes结缚,這里要節(jié)后的組件為Title和Content
static contextTypes ={
color: PropTypes.string
}
這樣傳遞過來,Title和Content就拿到this.context對象软棺,里面包含color屬性掺冠,則能在Title和Content中使用了
- Title:
render() {
return (
<div style={{color: this.context.color}}>
這里是標題部分
</div>
)
}
- Content
render() {
return (
<div style={{color: this.context.color}}>
這里是內(nèi)容部分
</div>
)
}
通過以上,就繞過Header和Main码党,直接將根節(jié)點的屬性傳遞到了孫組件Title和Content里面,這樣子組件誰想要誰接收這個屬性就行了就行了斥黑。
接下來考慮如何在孫組件Header或者Content中去改變這個屬性呢揖盘?
比如在Content組件, 注意:這個屬性是根節(jié)點的狀態(tài),狀態(tài)是自能自己改的锌奴。所以我們需要在根組件兽狭,也就是HomePage定義一個個方法,誰需要改鹿蜀,就把這個方法當屬性傳給誰箕慧。
HomePage:
static childContextTypes = {
color: PropTypes.string,
setColor: PropTypes.func
}
getChildContext() {
return {
color: this.state.color,
setColor: this.setColor
}
}
setColor = (color) => {
this.setState({color})
}
接下來在需要改變這個屬性子組件接受這個方法:并在事件中調(diào)用context的方法
static contextTypes ={
color: PropTypes.string,
setColor: PropTypes.func
}
render() {
return (
<div style={{color: this.context.color}}>
這里是內(nèi)容部分
<button onClick={() => this.context.setColor('green')}>變?yōu)榫G色</button>
<button onClick={() => this.context.setColor('yellow')}>變?yōu)辄S色</button>
</div>
)
}
注意點擊事件的寫法,確保this指向正確茴恰。
- 特別注意:上下文必須父子組件間颠焦。react-redux里的Provider是通過上下文實現(xiàn)的