深入理解react高阶组件+代码小例

高阶组件(HOC)是react中对组件逻辑进行重用的高级技术。但高阶组件本身并不是React API。它只是一种模式,这种模式是由react自身的组合性质必然产生的。具体而言,高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。新组件承受业务逻辑,并将数据传入给接收的组件,接收的组件变成UI组件,只负责使用数据,而生成的新组件称为容器组件。

原来react使用混入(mixins)技术来解决交叉问题,但是react意识到混入(mixins)技术产生的问题要比带来的价值大(react为何移除mixins 这篇博文可以看下),所以也就有了高阶组件来解决交叉问题。

下面通过一个小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函数设置新数据。
  • 卸载组件时, 移除监听函数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值