用簡單的話來講,主要是爲了更大程度的複用現有代碼,抽離代碼而產生的一個模式
高階組件的參數能夠爲一個組件,經過一個組件再去生成另外一個組件
用官方的例子來解釋:
現有一個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) );