Add Lifecycle Hooks to a Functional Stateless Component using Recompose

Tim Kindberg
InstructorTim Kindberg

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 3 years ago

Learn how to use the 'lifecycle' higher-order component to conveniently use hooks without using a class component.

[00:00] I'm going to write a higher order component called withConfig, and it's going to use the lifecycle Higher Order Component, from Recompose. It's essentially an escape hatch to the full React createClass API, except for the render method, which is not allowed.

[00:16] I'm going to listen on componentDidMount, and the point of my withConfig higher order component is to fetch a configuration. I'll listen on this config promise which contains the data I need, and then I'll set the state to the config.

[00:38] It's important to note that anytime you use setState inside of lifecycle, the state actually gets converted to props when it gets passed into the wrapped component. I'll show that more in a second.

[00:50] I'm also going to use getInitialState so that I can return an empty config. I've mocked out a configuration, so I just need to call this fetchConfiguration method, and it's going to return to me this config object.

[01:09] They're currently turned on because I'm actually passing them in as props to my dumb component. I'd like to be able to delete this completely and just have my configuration take care of it.

[01:22] Now they're gone, and we'll replace it with my higher order component. Let's make a call to fetchConfiguration and store it in the config promise that my component didMountHook is listening on.

[01:37] I want to make sure this is only called once for the entirety of my application. That way if multiple components use this higher order component, they won't each trigger a network call. That's why I do it outside of the higher order component.

[01:52] Now. I'm going to wrap user in the withConfig higher order component, and I'm going to replace these two config properties with just config, which we're getting from this setState call, which, as you remember, gets passed in as a prop, not as state, since functional stateless components don't have state.

[02:17] On the config, there's a show status, so I'm going to add config. in front of that. There's also a canDeleteUsers, so I'm also going to prepend config. there, as well. Should be able to refresh, and we have our options back. We can now change them, and we can see that they're going away.

[02:44] Lastly, I just want to note that any hook can be used here, as I had said. That includes things like shouldComponentUpdate or componentWillMount, etc.

Tim Kindberg
Tim Kindberginstructor
~ 5 years ago

I updated the example to use the state property instead of getInitialState method because Recompose updated their library to remove all usages of React.createClass.

Marc Schneider
Marc Schneider
~ 5 years ago

Could you please explain the benefit of doing it this way instead of using React.Component?

Tim Kindberg
Tim Kindberginstructor
~ 5 years ago

There is absolutely nothing wrong with using React.Component especially for one-off lifecycle connections.

But if you are already writing with a lot of HOC patterns or if you'd like to create a reusable HOC that needs to use a hook, I like the succinct API of recompose's lifecycle helper. I like not having to write the render method and spreading the props; it's just boilerplate noise IMO.

I personally have a love for simple functional stateless components that are decorated by composed higher-order components. So moving the hook from the component allows me to still use a functional stateless component as well.