react hoc_如何使用HOC模式开发React超能力

react hoc

Hey everyone! ? I hope you had a Merry, Merry Christmas and a Happy New Year!

嘿大家! ? 希望您过得愉快,圣诞快乐,新年快乐!

2018 has reached its end and it makes sense for me to start the new year with an article about Higher-Order Components!

2018年即将结束,对于我来说有意义的是以关于高阶组件的文章开始新的一年!

I’ve promised you to write about it since we’ve approached the subject when we’ve talked about the render props and the container patterns so it makes sense to deep dive a little bit and pay attention to it!

我已经答应过您,因为我们在谈到渲染道具和容器模式时已经接近了这个主题,因此有必要深入研究并注意它!

Personally it’s not one of my favourite patterns, but it’s a powerful tool to know, master and hang on your tool belt.

就个人而言,这不是我最喜欢的模式之一,但它是了解,掌握和掌握工具带的强大工具。

Just keep in mind that you should not overuse it. Almost everything that you can encapsulate in a HOC you can certainly implement using the render props pattern — check my article about render props here — and vice-versa.

请记住,您不应过度使用它。 几乎所有的东西,你可以在一个HOC封装可以使用道具呈现一定模式实施-检查我的约渲染道具文章在这里 -反之亦然。

01.什么是高阶组件? (01. What is a Higher-Order Component?)

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API. They are a pattern that stems from React’s nature that privileges composition over inheritance.

高阶组件(HOC)是React中用于重用组件逻辑的高级技术。 HOC并非React API的一部分。 它们是一种模式,源于React的本质,即特权优先于继承。

JavaScript is a well-suited language for functional programming as it can accept higher-order functions. A higher-order function is a function that can take another function as an argument and/or that returns a function as a result.

JavaScript是一种适合函数式编程的语言,因为它可以接受高阶函数。 高阶函数是可以将另一个函数作为参数和/或返回结果的函数。

In the same way, a higher-order component is a function that takes (wraps) a component and returns a new component.

同样, 高阶组件是一个接受(包装)组件并返回新组件的函数。

Higher-order functions allow us to abstract over actions, not just values.

高阶函数使我们可以抽象动作,而不仅仅是值。

HOCs are common in third-party React libs, such as Redux or React Router. I bet you’ve used some of them, maybe without being aware of it.

HOC在第三方React库中很常见,例如Redux或React Router。 我敢打赌,您可能已经使用了其中一些,也许没有意识到。

The main purpose of a higher-order component in React is to share common functionality between components without repeating code.

React中高阶组件的主要目的是在组件之间共享通用功能而无需重复代码。

02.高阶组件的类型 (02. Types of Higher-Order Components)

Basically there are two main types of HOC implementation: Props Proxy and Inheritance Inversion.

基本上,HOC实现有两种主要类型: Props ProxyInheritance Inversion

道具代理(ppHOC) (Props Proxy (ppHOC))

Props Proxy HOCs are elementarily expressed like this:

道具代理HOC基本表示为:

It’s nothing more than a function, propsProxyHOC, that receives a Component as an argument (in this case we’ve called the argument WrappedComponent) and returns a new component with the WrappedComponent within.

它不过是一个函数propsProxyHOC,该函数接收Component作为参数(在本例中,我们称为参数WrappedComponent)并返回其中包含WrappedComponent的新组件。

Have in mind that when we return the WrappedComponent, we also pass thru the props that the HOC receives. This explains the name given to this type: props proxy.

请记住,当我们返回WrappedComponent时,我们还会通过HOC收到的道具。 这解释了为此类型指定的名称: props proxy

When we return the Wrapped Component we have the possibility to manipulate props and to abstract state, even passing state as a prop into the Wrapped Component.

当我们返回包装组件时,我们就有可能操纵道具并抽象状态,甚至可以将状态作为道具传递给包装组件。

You can also wrap the Wrapped Component with other JSX elements changing its UI according to your app needs.

您还可以将包装组件与其他JSX元素包装在一起,以根据您的应用程序需求更改其UI。

Props Proxy HOCs are useful to the following situations:

道具代理HOC在以下情况下很有用:

  1. Manipulating props

    操纵道具
  2. Accessing the instance via Refs (be careful, avoid using refs)

    通过Refs访问实例(注意, 避免使用refs )

  3. Abstracting State

    抽象状态
  4. Wrapping/Composing the WrappedComponent with other elements

    用其他元素包装/组成WrappedComponent
继承反转(iiHOC) (Inheritance Inversion (iiHOC))

Inverted Inheritance HOCs are elementarily expressed like this:

反向继承HOC基本表示为:

In this situation the returned class extends the WrappedComponent. It is called Inheritance Inversion, because instead of the WrappedComponent extending some Enhancer class, it is passively extended. In this way the relationship between them seems inverse.

在这种情况下,返回的类将扩展 WrappedComponent。 之所以称为继承反转,是因为它是被动扩展的,而不是WrappedComponent扩展了某些Enhancer类的。 这样,它们之间的关系似乎是相反的

Inheritance Inversion gives the HOC access to the WrappedComponent instance via this, which means you can use the state, props, component lifecycle and even the render method.

继承反转给通过 HOC访问WrappedComponent情况下,这意味着你可以使用的状态,道具,组件的生命周期, 甚至渲染方法

Inversion Inheritance HOCs are useful for the following situations:

反转继承HOC在以下情况下很有用:

  1. Render Highjacking

    渲染劫持
  2. Manipulating state

    操纵状态

03.弄脏我们的手 (03. Getting our hands dirty)

Okay everyone ?to illustrate a bit the concepts presented above, let’s do some code.

大家好吗?为了稍微说明一下上面介绍的概念,让我们做一些代码。

If you want to play later with the code we’re doing, you can pull it here from this repo of mine ?.

如果您想稍后使用我们正在执行的代码,可以将其从我的这个仓库中拉出来。

Let’s try to implement a component that returns a welcome message according to the user which is logged into the system.

让我们尝试实现一个组件,该组件根据登录到系统的用户返回欢迎消息。

I’ve tweaked my App.js component to show some text and to render a component called Welcome to which I pass the prop user.

我已经对App.js组件进行了调整,以显示一些文本并渲染一个名为Welcome的组件,并将prop用户传递给该组件。

Ok, we can do that with a simple component like this:

好的,我们可以使用一个简单的组件来做到这一点:

But…

但…

What if I want the component to return Welcome Guest if no user is logged in?

如果没有用户登录,我希望组件返回“欢迎访客”怎么办?

Well… I can do that in the same Welcome component, with a simple if that checks if the user prop exists and if not it simply returns “Welcome Guest”.

好吧……我可以在同一个Welcome组件中执行此操作,并带有一个简单的if检查用户道具是否存在,如果不存在,它将简单地返回“ Welcome Guest”。

But let’s suppose I want to encapsulate that logic to use with multiple / different Welcome Components.

但是,让我们假设我想封装该逻辑,以与多个/不同的Welcome组件一起使用。

So the way to go is to make a Props Proxy HOC:

因此,方法是制作一个Props Proxy HOC:

What have we done here? We kept our Welcome component simple and we’ve created a JavaScript function called withUser which gets the Welcome component (WrappedComponent) as an argument and checks if the prop user exists. If it doesn’t it just returns a simple “Welcome Guest!” message.

我们在这里做了什么? 我们使Welcome组件保持简单,并创建了一个名为withUserJavaScript函数,该函数获取Welcome组件(WrappedComponent)作为参数并检查prop用户是否存在。 如果不是,它将仅返回一个简单的“ Welcome Guest!”(欢迎客人!) 信息。

This is very useful. Imagine you had 30 Welcome components in different languages (silly example but it makes the point of encapsulating the logic into a HOC).

这非常有用。 想象一下,您有30种用不同语言编写的Welcome组件(愚蠢的示例,但这很重要,是将逻辑封装到HOC中)。

Nice, so now we have a HOC to check if there’s a user logged in, otherwise it throws a Welcome Guest Message!

很好,所以现在我们有一个HOC来检查是否有用户登录,否则将引发“欢迎来宾消息”!

Let’s imagine now that the user info is coming from an external API (Auth0 for example) and is getting into our frontend application thru a Redux reducer which manages the App state.

现在让我们想象一下,用户信息来自外部API(例如Auth0),并通过管理应用程序状态的Redux reducer进入前端应用程序。

So before checking if there’s a user we need to check if the data isLoaded into the system!

因此,在检查是否有用户之前,我们需要检查数据是否已加载到系统中!

Wow! This way we could show a loading message while data is not loaded!

哇! 这样,我们可以在未加载数据时显示加载消息!

So… for this use case I guess we want to do some render highjacking and render another thing if data is not loaded.

所以……对于这个用例,我想我们想做一些渲染劫持行为,如果没有加载数据则渲染另一件事。

For render highjacking we need to use a iiHOC. Wow! Such a coincidence! So let’s do it and compose the two HOCs together everyone ? This will hit hard on the head of the nail.

对于渲染劫持,我们需要使用iiHOC。 哇! 真是巧合! 那么,让我们一起做这两个HOC吧? 这将严重打击指甲。

Pay attention to what we’ve done:

注意我们所做的事情:

We’ve created a withLoader iiHOC which extends the WrappedComponent. This way it can access its props and trigger different rendering.

我们创建了一个withLoader iiHOC,它扩展了WrappedComponent。 这样,它可以访问其道具并触发不同的渲染。

In this situation we are getting the isLoaded prop and if it’s not loaded we simply return a loading message! Otherwise we let the WrappedComponent render by simply returning super.render().

在这种情况下,我们将获取isLoaded道具,如果未加载,则只需返回一条加载消息! 否则,我们只需返回super.render()即可让WrappedComponent呈现。

In the export statement we are just composing two JavaScript functions such as f1(f2(f3))). Nothing more than that!

在export语句中,我们仅组成两个JavaScript函数,例如f1(f2(f3)))。 仅此而已!

There are tools to compose functions in a prettier way, but that’s another story for another article!

有一些工具可以更漂亮地构成函数,但这是另一篇文章的另一个故事!

04.最后但并非最不重要的 (04. Last but not least)

I’ve tried to use simple examples for you to grasp the concepts in the most clean way possible.

我尝试使用简单的示例来帮助您以最干净的方式掌握概念。

My advice for you is that if you do not master this concepts please pull my repo here and play with it a little bit.

我对您的建议是,如果您不掌握此概念,请在此处拉出我的存储库然后再使用它。

Check the code and try to understand it line by line.

检查代码并尝试逐行理解它。

It takes some time to get used to and feel comfortable doing this kind of abstraction so don’t loose your motivation or your focus with HOCs.

进行这种抽象需要花费一些时间来适应和适应,因此不要失去使用HOC的动力或关注重点。

Also as I said before, everything we’ve done here can be attained with render props or container pattern, so it’s not a must to choose a HOC or two to do clean code with this kind of encapsulation!

就像我之前说的,我们在这里所做的一切都可以通过渲染道具或容器模式来实现,因此,不必选择一两个HOC来使用这种封装来编写干净的代码!

I hope you had as much fun reading this article as I had writing it! If you really enjoyed it please give me some claps (not less than 50 please) ? and always remember to “Be Strong and Code On!”

希望您阅读这篇文章和写这篇文章一样开心! 如果您真的喜欢它,请给我一些鼓掌(请不少于50个)? 并永远记住“坚强并编码!”

Also if you want more deep and complex explanations please feel free to read the links I’ve added to the Bibliography section below ?

另外,如果您想要更深入,更复杂的解释,请随时阅读我添加到下面书目部分的链接吗?

05.参考书目 (05. Bibliography)

  1. React Documentation

    React文档

2. Eloquent Javascript

2. 雄辩的Javascrip t

3. React Higher Order Components in depth

3. 深入React高阶组件

Thank you very much!

非常感谢你!

evedes, Dec 2018

evedes,2018年12月

翻译自: https://www.freecodecamp.org/news/how-to-develop-your-react-superpowers-with-the-hoc-pattern-61293651d59/

react hoc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值