React.CreateContext
阿新 • • 發佈:2018-12-09
跨元件傳遞的內容元件,該元件匯出兩個物件Provider 提供資料, Consumer, 消費資料
簡單的使用
// 建立上下文
let {Provider, Consumer} = React.createContext()
// 假設我們有很多個元件,我們只需要在父元件使用Provider提供資料,然後我們就可以在子元件任何位置使用Consumer拿到資料,不存在跨元件的問題
// 提供資料
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
let {Provider, Consumer} = React.createContext()
// 父元件
function Parent (props) {
return (
<div>
<div>Parent: </div>
<Son></Son>
</div>
)
}
// 子元件
function Son (props) {
return (
<div>
<div>Son: </div>
<Child></Child >
</div>
)
}
// 孫子元件
function Child (props) {
return (
<Consumer>
{value => <div>
value: {value}
</div>}
</Consumer>
)
}
ReactDOM.render(<Provider value="1">
<Parent />
</Provider >, document.getElementById('root'));
簡單理解
思路:
1.自己新建兩個元件Provider,Consumer
2.Provider有一個引數value
3.在Provider元件內遍歷子元件,
4.如果元件是Consumer的話,就返回一個元件,並將value作為值傳遞給新建立的子元件Consumer
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
class Provider extends Component{
/**
* 處理渲染子元件Consumer
* @param {object} obj 需要迴圈的子元件
* @param {anything} value 定義的任何值
*/
initChild (obj, value) {
if (Array.isArray(obj)) {
// 這裡應該是遞迴呼叫,實現深度組建的處理
// 這裡僅作為簡單的理解(其實是我寫不出來,哈哈哈哈)
obj = obj.map(child => {
return this.initChild(child, value)
})
} else {
// 如果元件是Consumer 就克隆一個新的元件返回,
// 因為這裡拿到的Consumer是一個物件,並不能直接使用,所以需要使用 React.cloneElement克隆一個新的物件返回
if (obj.type.name === 'Consumer') return React.cloneElement(obj, {value})
}
return obj
}
render () {
// 拿到子元素
let {children, value} = this.props
children = this.initChild(children, value)
// 先判斷子元件是一個還是陣列,假如是陣列,則遍歷處理
return (
<React.Fragment>
{children}
</React.Fragment>
)
}
}
class Consumer extends Component{
render () {
return this.props.children(this.props.value)
}
}
// 這裡使用自己寫的元件
ReactDOM.render(<Provider value="1">
<Consumer>
{
value => <div>{value}</div>
}
</Consumer>
<div>1-1</div>
<Consumer>
{value => `2-${value}`}
</Consumer>
</Provider>, document.getElementById('root'));
總結
一定要敢寫,雖然不一定寫的出來,但是肯定會有收穫。。。。。。