一、简介
如我们所知,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"/> } }
2、演示截图