8

In my React component I have a form with onSubmit function

<form className="form-horizontal" name="taskForm" onSubmit={this.submitTask}>

submitTask(e) {

  e.preventDefault();
  console.log(this.props);  // undefined
  console.log(this) // window object
}

For some reason this.props is not in scope when I use form onSubmit. When I console.log(this.props) in the constructor, props logs out normally.

When I console.log(this) it is the window object. How do I get the scope of the react component?

Nearpoint
  • 7,202
  • 13
  • 46
  • 74
  • 3
    `onSubmit={this.submitTask.bind(this)}`. **[Link](http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/)**. – Tahir Ahmed Mar 09 '16 at 02:56
  • 3
    Tahir is correct, though I would recommend binding the function in your constructor and not inside your `render` method, so that it binds only once, not everytime you call render. Another way without binding would be `onSubmit={event => this.submitTask(event, this.props)}` – azium Mar 09 '16 at 03:17
  • 1
    @azium 's response should be the correct answer... you have full access to props, functions and all. – Mussser Sep 01 '16 at 02:22

1 Answers1

10

This is more broad problem, because similar behavior with this you will notice when you use other component events for example (onClick, onChange, onSubmit)

In documentation there is note about it:

https://facebook.github.io/react/docs/reusable-components.html#no-autobinding

Methods follow the same semantics as regular ES6 classes, meaning that they don't automatically bind this to the instance. You'll have to explicitly use .bind(this) or arrow functions =>.

As it is described you have to bind those methods or use arrow functions. If you choose binding, then you can bind in constructor or strictly in rendered component.

In constructor:

constructor(props) {
  super(props);
  this.submitTask = this.submitTask.bind(this);
}

In rendered component:

<form className="form-horizontal" name="taskForm" onSubmit={this.submitTask.bind(this)}>

With arrow function you can pass submitTask content to arrow function:

<form className="form-horizontal" name="taskForm" onSubmit={e => {
  e.preventDefault();
  console.log(this.props);  // undefined
  console.log(this) // window object
}}>
Krzysztof Sztompka
  • 7,066
  • 4
  • 33
  • 48