Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 1083 of the free egghead.io lessons, plus get React content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Write a Higher Order Component from Scratch

3:15 React lesson by

Learn the proper patterns for writing a higher order component from scratch.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Learn the proper patterns for writing a higher order component from scratch.

Avatar
Jason

It's awkward how most of these egghead videos start off as if you're halfway through the series already. There's no intro or anything, you just jump right into a full page of code as if you're already 5 videos deep.

In reply to egghead.io
Avatar
Anderson Faria Santos

The same feeling right now.

In reply to Jason
Avatar
Tim

That's actually the egghead way of doing things. The videos get right to the point so as to not waste your time. Hence the tag line "bite-size" learning. I can see how it would be jarring though without some prerequisite knowledge of the related topics (react, etc). Let me know if there is anything I can clarify!

In reply to Jason
Avatar
Greg

I really appreciate this way of doing things. No fluff. Just straight to the point.

In reply to Tim
Avatar
Austin Witherow

Why should I be writing 'high order components'? I do not understand what they do for me, it seems like a lot of abstraction with no clear benefit.

Avatar
Jason

I appreciate the no fluff approach, however I don't think a short intro of what's going on would be fluff. It just seems like you started watching a movie that already started an hour ago, it feels like you missed something.

In reply to Greg
Avatar
Jason

Austin you nailed it, this was my point. There's actually a lot of benefits from higher order components, but it's not being explained. That's where some type of small intro to these videos would not only be extremely beneficial but in some cases crucial to understand the material. I understand that egghead tries this 'bite size' approach of training which is fine, it's great for breaking up the material but that's not a replacement method of teaching if you don't have some context with a beginning, middle and end.

In reply to Austin Witherow
Avatar
Tim

I think the remaining lessons in the course help answer your question through various examples. I'm optimistic that by the end of the course you'll have a clear understanding of why you might use HOCs. This particular lesson was added to the beginning to demystifying what HOCs do "under the hood". I could move it later in the course after learners have gotten some initial exposure to some several real world examples.

In reply to Austin Witherow
Avatar
Austin Witherow

Alright Tim, I trust you and I will give it a go! A short introduction is always useful in any case, for my taste. But opinions opinions.

Thanks for the quick reply thumbsup

In reply to Tim
Avatar
Tim

It's good feedback. Thank you.

In reply to Austin Witherow

A higher order component typically always has the same structure. It takes in a BaseCompenent and it returns a component, in this case, it's a functional stateless component. Then it renders out the BaseCompenent and it spreads -> ... the props in.

index.js

const { Component } = React;

const hoc = {BaseComponent} => (props) =>
    <BaseComponent {...props} />;

Now, if we create another User and we pass our first User to our higher order component -> hoc, it's not going to modify it in any way, but we will have a valid React component. I just have to add the name. You see, the prop signature is identical to User, and it renders exactly the same.

const hoc = {BaseComponent} => (props) =>
    <BaseComponent {...props} />;

const User = ({ name }) =>
    <div className="User">{ name }</div>

const User2 = hoc(User);

Names

Now if we want our higher order component to actually do something, typically you add a configuration step. Here we'll take in some props we'd like to override and then we can spread those onto the component as well. Now, we have to use our configuration phase and pass in any prop that we'd like to override.

const hoc = (overrideProps) => {BaseComponent} => (props) =>
    <BaseComponent {...props} {...overrideProps} />;

...

const User2 = hoc({ name: 'Bob' })(User);

Now the name will always be 'Bob', regardless of what I change the name in the JSX. You could save the configuration portion of the higher order component call into a variable. We can call this one alwaysBob, sometimes that's nice for readability. Then we can name our higher order component properly, as well.

const overrideProps = (overrideProps) => {BaseComponent} => (props) =>
    <BaseComponent {...props} {...overrideProps} />;

...

const alwaysBob = overrideProps({ name: 'Bob' });
const User2 = alwaysBob(User);

Another reason you might want to create a higher order component is to tap into a lifecycle hook. In this case, I need to use a class component and we have to do the same thing where we return the BaseCompenent and spread the props in. Perhaps we want to create a component that never updates.

We could tap into the shouldComponentUpdate() method, and we can return false. We don't need a configuration step for this phase. We can call this neverRender.

const neverRender = {BaseComponent} => 
    class extends Component {
        shouldComponentUpdate() {
            return false;
        }
        render() {
            return <BaseComponent {...this.props} />;
        }
    };

...

const User2 = neverRender(User)

Now, User2 will never render.

Now, if Steve were bound to some data and it changed the update would not be reflected.



HEY, QUICK QUESTION!
Joel's Head
Why are we asking?