React for Beginners #5 — Events, Refs and the Strangeness of This

This is part 5 of my React Learning series. Using knowledge gleaned from www.reactforbeginners.com amoung other sources.

Last time we explored:

  • Props
  • Stateless functional components
  • React Router

So far we have been interested in displaying things. Now lets start looking at how we …react to what the user might do via events and form submissions as well as a common trap involving the “this” keyword

Basic Events in React

Events are how React functions when something happens, such as a button being clicked or a form being submitted. They are used quite a bit in JS, you might know that.

One main difference in React is they are done inline:

<button onClick={this.handleClick}>Click Me</button>

Where handleClick is a function available to the component. there are alot of ‘on’ events to choose from. Note you do not include paranthesis, else it will run on mount. Note that they are camel cased too, this is something I tend to assume in regular JS so it is good for me

For very simple functions you can even add them inline within the button, which seems like blasphemy but can have its uses.

That’s the basics of events, as always you can read more from the React Docs.

Submitting a Form

Like the button, we include an event on the form tag:

<form onSubmit={this.handleSubmit}>

Let’s assume the handleSubmit method is just a console.log(“Hi”) for now. We should expect ‘Hi’ right?

Nope, because the default behavior is to refresh the page

We can pass the event object to the method to allow handleSubmit to stop the refreshing behaviour with the following method:

event.preventDefault();

Now we will see the console.log as the page wont refresh.

Taking an input and Routing based on that

In this example, let’s assume we want a form that goes to a user profile based on an input’s value.

The method currently looks like this:

We need to do two things:

  1. Get the text from the input
  2. Change the page to /profile/INPUTVALUE

Getting the text from an input properly

We don’t want to just pick it up from the DOM, the DOM should be result, not take part in performing a task. Well there is two ways we can do this. First is state which we will get to and generally is the prefered method, but another way is refs which we will use this time around.

Refs

A ref, references a DOM element so a method can do things with it. This has had many forms over the years but this implementation is the most modern…at time of writing:

  1. Add a prop on the input tag: ref={this.myInput}
  2. Create a ref at the start of the component: myInput = React.createRef();

That’s how we ref nowadays. Now we can reference the dom node in any methods on the component. Yay!

Wait no we can’t…just doing this within a method however will cause an error! It won’t be able to find the ‘this’ that has myInput. This is quite wierd. this should be the component right?

“this” and Binding Methods

Let’s take a slight aside…

Well react has binding methods, these built-in methods bind this to the component, normally this is what we use. However a component's own unique methods dont have that binding by default because the components extend React.Component This does not automagically pass to methods we make ourselves in a component.

A solution to this is to bind our own methods, there is two ways to do this:

A constructor function — hopefully you recall from ES6 classes we can make a constructor function and define our methods in there:

That is tad confusing, but the bind makes sure that the goToProfile’s ‘this’ is the ‘this’ of the constructor which is the component…ouch my poor head!

A new way (which is probably going to be old by the time you see it) is changing the method to a property that is an arrow function

Old Method: goToProfile(event) {}

New Property: goToProfile = (event) => {};

The arrow function binds this

In short, if you want to access this inside a custom method, turn it into a property with a fat arrow function. Something like this:

Getting a value from an input

Now the component is capturing details about the input when there is a form submit via a ref.

When the goToProfile method is run, we have asked it to console.log(this), the this here is the component. But we can drill deeper:

  • this.myInput will return the reference
  • this.myInput.value will return the input for which the ref was placed.
  • this.myInput.value.value will return the value of the input

As you can see there is quite a few layers involved here! It’s a good idea to put this into a variable when we use to to go to that URL.

Change the URL without refreshing the page using Push State and React Router

Now we can access the data from the form submission we can use it to direct us to the relevent URL.

To do this we use a React Router method called push. We have access to React Router since StorePicker is a child of the Router component, so when we look in react dev tools we can see the props that are given by React Router. Push method is actually in an object called history, so the command we want is:

this.props.history.push(`/profiles/${profileName}`)

Note the backticks, and dollar sign. We are using a template string here.

And success! we will route to /profiles/profileName where profileName is the variable recording the value of the input which is the value of the ref which is on the component.... that simple!

Note how fast it is, react router just needs to swap out the component, and doesnt need to load the whole page. Thats pretty cool! We are starting to scratch the surface of React magic.

Conclusion

Hopefully that was fairly straightforward to cover very the basics. I would advise, like everything, to check the react docs on this. Refs in particular are supposed to be a tool to be used for specific circumstances, maybe, that’s a debate for another person’s blog!

We will return to user input again at a later post where things get a bit more interesting as we delve more deeply into State…

--

--

All about the things I bumble into as a Web Dev

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store