This happens because custom functions such as handleInput lose their this binding. If you attempt to access this.state, this.props or this.setState within them will result in the common error, and is solved by re-binding the functions in the constructor:

Here you can bind this when the function is passed as a prop. While it might be tempting to do this all over your application, this method has a huge downside. What it does is that it will create a new function every time that the render method executes, which for larger applications will be catastrophic while it might not be as noticable in smaller applications. For more information on this, you can read this case study.

"But wait, what about arrow functions?" - yes, you are right, you could also remove this function and do setState right there when passing the onChange prop.

While it might be easier to see what is going on here, it suffers from the same problem as the previous example. Now we are creating an anonymous function every time the render function executes, with the same performance issues as well.

Solving the problem

This means that the best way is indeed to bind the functions in the constructor if you want to avoid the performance issues. Then only one extra function is created when the component is created and that function will be used even if render executes again, without creating new ones every time.

"So that's it, I'm stuck with re-binding ALL my functions every time?!" - Thankfully, no. Here we can actually have the best of both worlds thanks to babel, which you are most likely already using to transpile your code. (If not, you probably should!). Babel uses presets and plugins and there are a ton of them. We are interested in a particular one, called transform-class-properties.

Conclusion

We encountered a bothersome problem, found out that the solutions that felt better to write has performance issues and that the solution to the bothersome problem is to write code the bothersome way - re-bind functions in the constructor. However, with the transform-class-properties babel plugin's help we can write arrow functions on the class that automatically binds, solving both problems and resulting in better code.