高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而造成的设计模式。
具体而言,高阶组件是参数为组件,返回值为新组件的函数。
还不了解高阶组件的点这里
最近在作项目的时候遇到了一个情形:在系统后台存在多个全局设置开关,例如在多个页面都须要请求会员设置的开关。若是在每一个须要调用全局设置的地方都去请求一下接口,就会有一种不优雅的感受,这个时候我就想到利用高阶组件抽象一下。html
getMemberSettingHoc = Component => class ContainerComponent extends React.Component { state = { loading: true, memberSetting: '' } componentDidMount() { Api.getSetting().then(memberSetting => { this.setState({ memberSetting }) }) ...doSomething } render() { return ( <Component {...this.props} memberSetting={this.state.memberSetting} /> ) } } // 使用高阶组件 class Home extends Component { ... } export default getMemberSettingHoc(Home);
这个时候看起来编写一个 getMemberSettingHoc 的高阶组件能够让咱们复用获取会员设置的逻辑react
这个时候若是又多了几个全局开关,例如:交易设置,支付设置,预定设置...编程
问题来了,这个时候咱们还须要编写更多的高阶组件来抽象这些设置吗?
答案是否认的,咱们能够实现一个 preMountHoc 来处理这些请求,顾名思义, preMountHoc 就是在挂载以前作事情的高阶组件。设计模式
代码以下函数式编程
const preMountDecorator = doSomething => ContentComponent => class PreMountComponent extends React.Component { }
咱们传入了一个参数,这个参数来传入要请求的接口 doList 和返回的字段 keyList ,在 PreMountComponent 挂载的时候去 doSomething, 而后经过props,传回给传入的 ContentComponent.函数
咱们看下代码this
// preMountHoc const preMountHoc = doSomething => ContentComponent => class PreMountComponent extends React.Component { constructor() { super(); this.state = { loading: true, result: {}, }; } componentDidMount() { const doList = get(doSomething, 'doList', []); const doListLength = get(doList, 'length') || 0; const keyList = get(doSomething, 'keyList', []); const keyListLength = get(keyList, 'length') || 0; if (doListLength == 0) { this.setState({ loading: false }); return; } Promise.all(doList).then((res) => { const result = {}; if (doListLength == keyListLength) { keyList.forEach((el, index) => { result[el] = res[index]; }); } else { doList.forEach((el, index) => { result[`pre_${index}`] = res[index]; }); } this.setState({ result, loading: false }); }); } render() { const { loading, result } = this.state; if (loading) { return <BlockLoading loading />; } return ( <ContentComponent {...result} {...this.props} /> ); } }; export default preMountHoc;
给 preMountHoc 传入的须要的请求和返回的字段名,就能够达到咱们的目的,来看看使用方法设计
class ScrmList extends Component { ... } export default preMountHoc({ doList: [settingApi.getPower(), settingApi.hasMemberThreshold()], keyList: ['memberStoreSetting', 'scrmConditionType'], })(ScrmList)
固然高阶组件也是装饰器,你也能够这么用code
@preMountHoc({ doList: [settingApi.getPower(), settingApi.hasMemberThreshold()], keyList: ['memberStoreSetting', 'scrmConditionType'], }) class ScrmList extends Component { ... } export default ScrmList;
高阶组件并非 React 的特性,是函数式编程的一种范式,最大的好处就是解耦和灵活性,在这分享下最近项目中的思考。component