React: 高阶组件(HOC)

一、简介

如我们所知,JavaScript有高阶函数这么一个概念,高阶函数本身是一个函数,它会接收或者返回一个函数,进而对该函数进行操作。其实,在React中同样地有高阶组件这么一个东西,称为HOC,它也是一个函数,但是与高阶函数不同的是,高阶组件操作的是组件,它会接收一个组件作为参数,然后返回另外一个组件。通常,HOC会使用一个能够维护State或者包含若干功能的类来包装输入的组件,父组件保留State或者将若干功能作为属性向下传递给参数组件,参数组件不需要知道HOC代码实现的具体细节,它允许用户构建更多的无状态函数式组件,专心的管理自己的界面UI。所以说,高阶组件是组件之间功能复用的最佳方式。

 

二、使用

使用高阶组件,将上一篇博文中的国家列表的数据加载逻辑、显示逻辑进行分离,步骤如下:

1、封装一个列表组件,将数据的展示逻辑封装起来

//1、封装一个列表组件,将展示的逻辑封装起来
const ListComponent = ({data, selected=""}) =>
    <select className="list" defaultValue={selected} style={{fontSize:20,color:'red'}}>
        {data.map(({name},i) => <option key={i} value={name}>{name}</option>)}
    </select>;

2、封装一个数据组件,将数据的请求过程封装起来

//2、封装一个数据组件,将parse和loading的过程封装起来,这个组件会接收一个ParameterComponent组件,和一个url请求地址
const DataComponent = (ParameterComponent, url) =>

    class DataComponent extends Component {

        constructor(props){
            super(props);
            this.state = {
                data:[],
                loading:false
            }
        }

        componentDidMount() {
            this.setState({loading: true});
            fetch(url)
          .then(response
=> response.json())
          .then(data => this.setState({loading:false, data:data})) } render(){ const {loading} = this.state; return ( <div className="data"> {(loading)? <div>now is Loading...</div> : <ParameterComponent {...this.state} {...this.props}/>} </div> ) } };

3、创建父组件,传入列表组件和url

//3、创建数据组件,传入列表组件和url
const Country = DataComponent(ListComponent,"https://restcountries.eu/rest/v1/all");

4、挂载父组件 

//导出
export default class App extends Component {
    render() {
        return <Country selected="China"/>
    }
}

//挂载
ReactDOM.render(
  <App />,
  document.getElementById('root')
);

 

三、结果

1、完整代码

import React, { Component } from 'react';
import fetch from "isomorphic-fetch";


//1、封装一个列表组件,将展示的逻辑封装起来
const ListComponent = ({data, selected=""}) =>
    <select className="list" defaultValue={selected} style={{fontSize:20,color:'red'}}>
        {data.map(({name},i) => <option key={i} value={name}>{name}</option>)}
    </select>;

//2、封装一个数据组件,将parse和loading的过程封装起来
const DataComponent = (ParameterComponent, url) =>

    class DataComponent extends Component {

        constructor(props){
            super(props);
            this.state = {
                data:[],
                loading:false
            }
        }

        componentDidMount() {
            this.setState({loading: true});
            fetch(url).then(response => response.json()).then(data => this.setState({loading:false, data:data}))
        }

        render(){
            const {loading} = this.state;
            return (
                <div className="data">
                    {(loading)? <div>now is Loading...</div> : <ParameterComponent {...this.state} {...this.props}/>}
                </div>
            )
        }
    };

//3、创建数据组件,传入列表组件和url
const Country = DataComponent(ListComponent,"https://restcountries.eu/rest/v1/all");

export default class App extends Component {

    render() {
        return <Country selected="China"/>
    }
}
View Code

2、演示截图

 

posted @ 2019-12-18 14:12  XYQ全哥  阅读(1428)  评论(0编辑  收藏  举报