Vue 2 Internal Features from the Ground Up

Challenge 7: Higher-Order Components

Evan You

Evan You

Creator of Vue.js
Vue 2 Internal Features from the Ground Up

Check out a free preview of the full Vue 2 Internal Features from the Ground Up course

The "Challenge 7: Higher-Order Components" Lesson is part of the full, Vue 2 Internal Features from the Ground Up course featured in this preview video. Here's what you'd learn in this lesson:

In this challenge, students create a helper that takes an inner component that expects prop and returns a higher-order component.


Transcript from the "Challenge 7: Higher-Order Components" Lesson

>> Evan: So this outer component basically becomes, it doesn't render anything of it's own, right? Which is interesting, like, we can do more things in this component actually, right? So this leads us into the next topic which is pretty common in the React world. It's a concept called higher-order components, okay?

So it sounds pretty fancy how many of you have heard of like, high order functions? Yeah. So, in functional programming you have this sort of, you have a original function, you can take that function compose it to return a higher order function. Which does additional things, but it still utilizes the original function internally.

But that's pretty abstract, so let's try to think about what a high order component could be in a, in a more practical case. So let's imagine we have a, let's go into 2.3, and we can see that
>> Evan: We have this Avatar component. This is a very, very simple component in that its sole responsibility is rendering some template.

But in real word use cases, you might have additional things. For example, you have styling associated with it. You have a more complex styling structure. But eventually you want to hide this all away, abstract the inside of this nicely reusable avatar component that you can use anywhere. And then, when you use it, the downside is, this avatar component is not that smart.

It expects you to give this full URL to the image that it should be displaying which isn't super nice. Like, in some cases, for example, you are working with a system where you only have the user name. And then you need to call an API to figure out what the avatar URL for that user is.

Then eventually you need to pass it to this avatar component. If you put that logic inside a parent component that is using avatar, you're essentially polluting this parent component with some logic that it should not really be concerned about with. Right, and this logic is going to be re-used in a lot places in your app because you don't want to be always passing a full, long URL.

You want to just, what you want is something like this, a smart component. All you need to give it is the username. And it figures out what the URL for this avatar should be and then pass it into this internal avatar component for you. So this smart avatar is essentially a component that abstracts away some repetitive logic, it separates that from both the parent context and this inner component.

So a very dedicated piece of responsibility. This inner component is now very, very dumb. It doesn't care about any logic it just takes some props and render it outer context is also unaware of anything going on. All it knows is I use this component. Give it a user name.

It will do the right thing. So this is a very nice encapsulation mechanism. It's like composing different layers of responsibility with components. Which is why this pattern has become very popular in the react world, because naturally, random functions are closer to functional programming and makes these patterns shine.

But because Vue can use random functions, so there's really nothing preventing you from applying the same technique in a Vue context if you really enjoy this kind of composition. So, let's take a look at our exercise. We have a mocked API function here. All it does is it takes a username and gives you back an avatar URL inside a callback.

And it fakes it with a 500 millisecond, delay. And it always give you the same URL which is the view logo. So it doesn't really matter what username you passed in. It's just for faking an API call. And now we have this base avatar component. Okay. And then we have this smart avatar component which we use like this inside our roots is this.

We've setup everything else for you. What you need to implement this function called withAvatarURL. This is something more like so called component enhancer or if you enable something like decorators. You can actually do something like this, which uses this function as a decorator so you don't have to call this something like that.

But eventually what this does is it returns another component which is here at smart avatar. So it's essentially returning another component. And that component, this smart avatar component, should be internally rendering this at its root. But it should maintain the logic of taking its username prompt, go to the API, find out the avatar for the, in the URL.

Pass it on to the inner avatar component. And also between the time where you're sending out the API and waiting for to come back you should be rendering the inner avatar component with the placeholder image.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now