react學習--高階元件
阿新 • • 發佈:2018-12-22
原來react使用混入(mixins)技術來解決交叉問題,但是react意識到混入(mixins)技術產生的問題要比帶來的價值大(react學習--react為何移除mixins 這篇博文可以看下),所以也就有了高階元件來解決交叉問題。
高階元件(HOC)是react中對元件邏輯進行重用的高階技術。但高階元件本身並不是React API。它只是一種模式,這種模式是由react自身的組合性質必然產生的。具體而言,高階元件就是一個函式,且該函式接受一個元件作為引數,並返回一個新的元件。新元件承受業務邏輯,並將資料傳入給接收的元件,接收的元件變成UI元件,只負責使用資料,而生成的新元件稱為容器元件。
下面通過一個小demo來看一下高階組建的應用。
資料和一些方法:
//資料和一些方法 const Datasource = { data: { // 存放資料 comments: [ {id: 1, title: '今天是個好日子'}, {id: 2, title: '心想的事兒都能成'} ], blogPost: [ {id: 1, title: '床前明月光'}, {id: 2, title: '疑是地上霜'}, ] }, getComments () { return this.data.comments }, getBlogPost () { return this.data.blogPost }, handlers: [], addChangeListener (handler) { this.handlers.push(handler) }, removeChangeListener (handler) { this.handlers = this.handlers.filter(item => item !== handler) }, changeComments () { this.data.comments.push({ id: 3, title: '今個老百姓真開心' }) this.emit() }, changeBlogPost () { this.data.blogPost.push({ id: 3, title: '舉頭望明月' }) this.emit() }, emit () { this.handlers.forEach(handler => handler()) } }
UI元件1(木偶元件)
//UI元件 木偶元件 class CommentList extends Component { render () { return ( <div> <h2>CommentList</h2> <ul className = "list-group"> { this.props.lists.map(item => <li key = {item.id} className="list-group-item">{item.title}</li>) } </ul> </div> ) } } // 負責資料的邏輯處理,將其傳遞給UI元件, 此為容器元件 智慧元件 const Container = higherOrderComponent(CommentList, () => Datasource.getComments()) export default Container
UI元件2(木偶元件)
class BlogList extends Component {
render () {
return (
<div>
<h3>BlogtList</h3>
<ol className = "list-group">
{
this.props.lists.map(item => <li key = {item.id}
className="list-group-item">{item.title}</li>)
}
</ol>
</div>
)
}
}
export default higherOrderComponent(BlogList, () => Datasource.getBlogPost() )
高階元件:
const higherOrderComponent = (UIComponent, handler) => {
return class extends Component {
constructor () {
super()
this.state = {
lists: handler()
}
this.handleChange = this.handleChange.bind(this)
}
componentDidMount () {
Datasource.addChangeListener(this.handleChange)
}
componentWillUnmount () {
Datasource.removeChangeListener(this.handleChange)
}
handleChange () {
this.setState({lists: handler()})
}
render () {
return <UIComponent {...this.state}/>
}
}
}
export default higherOrderComponent
父元件:
class HocExample extends Component {
render () {
return (
<div>
<button onClick = { Datasource.changeComments }>change comments</button>
<CommentList/>
<BlogPost/>
</div>
)
}
}
簡要講解:
- 掛載元件時, 向
DataSource
新增一個監聽函式。- 在監聽函式內, 每當資料來源發生變化,都是呼叫
setState
函式設定新資料。- 解除安裝元件時, 移除監聽函式。