Convert Imperative Code to a Declarative React Component

Jason Brown
InstructorJason Brown
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 5 years ago

In this lesson we'll show how to take a beforeUnload call and convert it to a declarative React Component. It will handle subscribing to events, and automatically unsubscribing to prevent memory leaks.

[00:00] React allows you to take imperative code, and turn it into a declarative and reusable component. You can see here in our componentDidMount(), we're adding an event listener to the window beforeUnload.

[00:12] This is an event that is fired when the window is tried to close, so that we can potentially alert our user that there's unsaved changes. To make this reusable, we'll first create another class. The class will be called beforeUnload.

[00:34] In our render function, we'll return react.children.only(this.props.children). What this will do is ensure that only a single child is being returned or passed in. Then if there is more than one child being passed in, it will warn us.

[00:53] We'll then go take some code that we've already in our componentDidMount(), and our componentWillUnmount(). We'll add them to our new component. We'll now also need to get our alert message. We'll add it to our new component as well.

[01:13] Because we'll be referencing this inside of our alert message, we'll also have to set up a constructor, pass in our props, call super. Then this.alertMessage equals this.alertMessage.bind(this). Now, we want the respond to the active flag that we pass in, we can add an if statement.

[01:35] Say if this.props.active, and place this inside of here. Any time we're passing in a truthy value, this will be executed. We can't just return and assign return value, this.props.active, because in some browsers, any time you assign anything here or return anything, it will be active, even if sometimes this is undefined or null.

[02:02] It just depends on the browser, so this is an easier way to provide cross-browser compatibility. Now, we're ready to use our component. First, we need to go remove this.alertMessage, because we moved it to our other component.

[02:14] Then rather than this div, we can replace it with beforeUnload. Then we can also pass in our active equals this.state.active. See here we have a button with an onclick. This will then call a toggle, and toggle our active state, and just give us a little indicator whether we're active or inactive.

[02:34] With this active, rather than a true or false, you might have editing, or you might have whatever else. As long as you're passing in a truthy value, the user will be alerted that they have something that needs to be fixed on the page before the page closes.

[02:49] Now, let's check it out in the browser. See here, we have our app with our active button. If we try to close our app, you can see that it asks us to stay or leave. In our case, we'll click stay. If we then click active again, it'll switch it to inactive.

[03:05] Now, if we try to close our window, because we're passing in a falsey value, it will allow us to close the window without actually popping up the confirmation message.

[03:15] Now, using an if statement like we have here in alertMessage might work in our case of beforeUnload, but there might be times where you need to actually figure out whether or not you need to remove the function attachment or add the function attachment.

[03:32] What we'll do is use componentDidUpdate() to figure that out. componentDidUpdate() will receive our previous props, and also have access to the current props. What we need to do is destructure active from our current props.

[03:47] Then we'll destructure active, and just call it wasActive, from our previous props. Now, we can write an if statement. If it was active before, and it's not active now, which means it went from true to false, that means we want to remove our event listener.

[04:09] However, if it wasn't active, and it's active now, that means it previously wasn't active, but now it is, that we should attach our event listener. Now, one other important note to make is that in our componentWillUnmount(), we must always call removeEventListener and remove the function that we're attaching it to.

[04:33] Otherwise, when this component gets unmounted right here, when this potentially disappears, we will still have a function attached to the window. That means we'll have a memory leak.

egghead
egghead
~ 32 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today