内容简介:简单来说高阶组件(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, 那么我们需要将 withData
、 withLoading
和 withLogger
组合起来。
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 封装成 withUserData
、 withCommentData
等等。
总结
- 通过 HOC 将一些代码逻辑封装起来,可增加代码的复用性,也方便后期维护。
- HOC + 组合函数,提升代码可阅读性。
- HOC + 柯里化,封装多参数的 HOC,进一步增加代码的复用性。
参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Responsive Web Design
Ethan Marcotte / Happy Cog / 2011-6 / USD 18.00
From mobile browsers to netbooks and tablets, users are visiting your sites from an increasing array of devices and browsers. Are your designs ready? Learn how to think beyond the desktop and craft be......一起来看看 《Responsive Web Design》 这本书的介绍吧!