[Solution] React - TypeError: Cannot Read Property of Undefined

This is a common error that all React developers run into at some point.

The most common situation to see it is when you call a function in your component that tries to access `this` (e.g. “this.setState”).

The reason you’re getting the error is because `this` is not defined inside your function.

Luckily, it’s an easy fix.

To resolve this error, you need to bind `this` to the function being called so that `this` will refer to the component scope, not the individual function scope.

There are a few different ways to do this, I’ll walk you through them and you can pick which one you like.

Fix 1 - Bind `This` In Your Constructor

This is the most common method to fix the error it.

Take a look at the example component below, particularly the constructor:

This function will give you the “cannot read property of undefined” error if you remove the line:

    this.handleSubmit = this.handleSubmit.bind(this)

By binding `this` to the `handleSubmit` function here, it ensures that any time the `this` keyword is called in that function, it will refer to the `this` object of the component instance (which has properties like `this.state`).

Important note: You’ll also need to bind `this` to functions that are passed down as props to child components. It’s good practice just to bind `this` to all your component functions in their constructors.

Fix 2 - Bind `This` When Invoking the Function

What if you don’t want to bind `this` to all your functions in your constructor.

An alternative option is to bind it when calling your function in your JSX.

In our example, this would also work:

        <input type="submit" value="Submit" onClick={this.handleSubmit.bind(this)} />

This typically isn’t a great approach because it’s easy to forget to bind `this` on functions when you call them. It’s easier just to define them like in the first fix.

Fix 3 - Use Arrow Functions

A final option that also works, and is the most convenient, is to use arrow functions to define your component’s functions.

Arrow functions implicitly bind `this` from the outer scope (the component) to the function, which means you don’t need to worry about it, which is nice.

This assumes you’re using Babel to transpile your code and can use ES6 JavaScript. Otherwise stick to the first 2 options.

Back to our example...

Changing our `handleSubmit` function to the following will also clear up the error:

  handleSubmit = (e) => {

    e.preventDefault()

    console.log(this.inputRef.current.value);

  }

The nice thing about this approach is that if you get in the habit of using arrow functions, you never have to worry about binding `this` to functions again.

Any of these 3 methods will work and effectively do the same thing, just pick the one that seems the simplest and most reliable for you.