React 高阶组件(HOC)实践

栏目: IOS · Android · 发布时间: 6年前

内容简介:简单来说高阶组件(HOC)就是一个函数,它接受一个组件作为参数然后返回一个新组件。HOC 主要用于组件之间逻辑复用。比如你写了几个组件,他们之间的逻辑几乎相同,就可以用 HOC 对逻辑进行封装复用。本文主要分享:这里介绍几个常用的 HOC

简单来说高阶组件(HOC)就是一个函数,它接受一个组件作为参数然后返回一个新组件。HOC 主要用于组件之间逻辑复用。比如你写了几个组件,他们之间的逻辑几乎相同,就可以用 HOC 对逻辑进行封装复用。

本文主要分享:

  • 如何封装 HOC
  • HOC + 组合函数,处理多个 HOC 嵌套问题
  • HOC + 柯里化,封装多参数的 HOC

如何封装 HOC

这里介绍几个常用的 HOC

withLogger

我们在调试代码时,经常都需要打印 props,所以可以将打印逻辑封装起来。

const withLogger = (prefix = "") => WrappedComponent => {
  const WithLogger = props => {
    console.log(`${prefix}[Props]:`, props);
    return <WrappedComponent {...props} />;
  };
  return WithLogger;
};
复制代码

使用:

withLogger('这里打印的是xxx')(Component)
复制代码

withData

组件中的获取数据的逻辑也可以抽离成 HOC,需要传入 url, param 两个参数。

import React, { Component } from "react";

const withData = (url, params) => WapperedComponent => {
  class WithData extends Component {
    state = {
      data: []
    };
    componentDidMount() {
      fetch(url, {body: JSON.stringify(params)})
         .then(response => response.json())
         .then(data => this.setState({ data }));
    }
    render() {
      return <WapperedComponent {...this.state} {...this.props} />;
    }
  }
  return WithData;
};

复制代码

使用:

withData(
  url: 'https://jsonplaceholder.typicode.com/posts',
  params: {
    _limit: 10,
    page: 2
  }
)(Component)
复制代码

withLoading

由于数据请求是异步的,为了不让用户看到一片空白,当数据请求还没有返回时,展示 Loading 组件。

const withLoading = Loading => WapperedComponent => {
  const WithLoading = props => {
    return props.data.length === 0 ? (
      <Loading />
    ) : (
      <WapperedComponent {...props} />
    );
  };
  return WithLoading;
};
复制代码

使用:

const Loading = () => <p>loading</p>;
withLoading(Loading)(Component)
复制代码

如何处理多个 HOC 嵌套问题

如果一个组件,需要请求数据,在数据未返回时展示 loading,还需要打印 props, 那么我们需要将 withDatawithLoadingwithLogger 组合起来。

const Loading = () => <p>loading</p>;
withData(
  "https://jsonplaceholder.typicode.com/posts",
  {
    _limit: 10,
    page: 2
  }
})(
  withLogger('xxx')(
    withLoading(Loading)(Component)
  )
)
复制代码

上面这种嵌套的方式可阅读性很差,这里用 compose 组合函数优化一下。

const compose = (...fns) => x => fns.reduceRight((x, fn) => fn(x), x);

const Loading = () => <p>loading</p>;
compose(
  withData(
    "https://jsonplaceholder.typicode.com/posts",
    {
      _limit: 10,
      page: 2
    }
  ),
  withLogger("这里是xxx"),
  withLoading(Loading),
)(Component);
复制代码

优化后的代码明显更为易读,当然如果你不习惯从下到上执行,你也可以写成 pipe 函数,只需要将 compose 函数中 reduceRight 方法改为 reduce 即可。

如何封装多参数的 HOC

我们注意到 withData 传入了两个参数,url 和 params,假如需要多次调用 withData ,比如:

withData(
    "https://jsonplaceholder.typicode.com/posts",
    {
      _limit: 10,
    }
)
withData(
    "https://jsonplaceholder.typicode.com/posts",
    {
      _limit: 9,
    }
)
withData(
    "https://jsonplaceholder.typicode.com/posts",
    {
      _limit: 8,
    }
)
复制代码

我们发现每次调用的 url 都相同,这里可以用柯里化函数将参数封装一下:

const curry = fn => {
  const loop = (...args) => args.length === fn.length
    ? fn(...args)
    : (...arg) => loop(...args,...arg)
  return loop
}

const withPostData = curry(withData)("https://jsonplaceholder.typicode.com/posts")

withPostData({_limit: 10})
withPostData({_limit: 9})
withPostData({_limit: 8})

复制代码

同理我们还可以根据不同的 url 封装成 withUserDatawithCommentData 等等。

总结

  1. 通过 HOC 将一些代码逻辑封装起来,可增加代码的复用性,也方便后期维护。
  2. HOC + 组合函数,提升代码可阅读性。
  3. HOC + 柯里化,封装多参数的 HOC,进一步增加代码的复用性。

参考


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程匠艺

编程匠艺

(美)古德利弗(Goodliffe, P.)著 / 韩江,陈玉译 / 电子工业出版社 / 2008-9 / 79.00元

如果你可以编写出合格的代码,但是想更进一步、创作出组织良好而且易于理解的代码,并希望成为一名真正的编程专家或提高现有的职业技能,那么《编程匠艺——编写卓越的代码》都会为你给出答案。本书的内容遍及编程的各个要素,如代码风格、变量命名、错误处理和安全性等。此外,本书还对一些更广泛的编程问题进行了探讨,如有效的团队合作、开发过程和文档编写,等等。本书各章的末尾均提供一些思考问题,这些问题回顾了各章中的一......一起来看看 《编程匠艺》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试