用简单的话来讲,主要是为了更大程度的复用现有代码,抽离代码而产生的一个模式
高阶组件的参数能够为一个组件,经过一个组件再去生成另外一个组件
用官方的例子来解释:
现有一个CommentList组件以下app
class CommentList extends React.Component { constructor() { super(); this.handleChange = this.handleChange.bind(this); this.state = { // "DataSource" 就是全局的数据源 comments: DataSource.getComments() }; } componentDidMount() { // 添加事件处理函数订阅数据 DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { // 清除事件处理函数 DataSource.removeChangeListener(this.handleChange); } handleChange() { // 任什么时候候数据发生改变就更新组件 this.setState({ comments: DataSource.getComments() }); } render() { return ( <div> {this.state.comments.map((comment) => ( <Comment comment={comment} key={comment.id} /> ))} </div> ); } }
同时有另外一个BlogPost组件以下:函数
class BlogPost extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { blogPost: DataSource.getBlogPost(props.id) }; } componentDidMount() { DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { DataSource.removeChangeListener(this.handleChange); } handleChange() { this.setState({ blogPost: DataSource.getBlogPost(this.props.id) }); } render() { return <TextBlock text={this.state.blogPost} />; } }
能够看出这两个组件中的结构基本一致,都是经过DataSource接收数据,而后监听,解除监听,而后渲染
那么咱们就能够将公共的部分提取出来,以下:this
// 函数接受一个组件参数…… function withSubscription(WrappedComponent, selectData) { // ……返回另外一个新组件…… return class extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { data: selectData(DataSource, props) }; } componentDidMount() { // ……注意订阅数据…… DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { DataSource.removeChangeListener(this.handleChange); } handleChange() { this.setState({ data: selectData(DataSource, this.props) }); } render() { // ……使用最新的数据渲染组件 // 注意此处将已有的props属性传递给原组件 return <WrappedComponent data={this.state.data} {...this.props} />; } }; }
而后就能够经过withSubscription组件来生成新的组件:code
const CommentListWithSubscription = withSubscription( CommentList, (DataSource) => DataSource.getComments() ); const BlogPostWithSubscription = withSubscription( BlogPost, (DataSource, props) => DataSource.getBlogPost(props.id) );