0

In my React/JS application. this is part of the Component class I have:

<p>
            <input
              onChange={ this.handleEmailChange } value={ this.props.email } type='email'
              className={ this.state.error ? 'form-control loginCredentialError shakeElement' : 'form-control' }
              name='email'
              placeholder='Email' required='True'
            />
            <input
              onChange={ this.handlePasswordChange } value={ this.props.password } type='password'
              className={ this.state.error ? 'form-control loginCredentialError shakeElement' : 'form-control' } name='password'
              placeholder='Password' required='True'
            />
          </p>
          <p>
            <Button
              onClick={ (event) => this.handleLoginClick(event) }
              className='btn btn-round-lg btn-round btn-primary btn-block center-block'
            >Sign In</Button>
          </p>

As you can see I have handleEmailChange, handlePasswordChange, and handleLoginClick. Those three functions are of the same Component class as the render function

In this function, the this is evaluated as null, which makes this.setState fail.

handleEmailChange(event) {
    const value = event.target.value;
    console.log(value);
    this.setState({ email: value });
  } 

however, in this function the this is fine and has a value. setState works well. Can anyone please let me know why the difference in these seemingly similar functions?

handleLoginClick(event) {
    event.preventDefault();

    const payload = {
      'email': this.state.email,
      'password': this.state.password,
    };

    this.setState({ communicating: true, error: false, errorServer: false });
...
...
...
JasonGenX
  • 4,952
  • 27
  • 106
  • 198

1 Answers1

3

This difference here is in binding. If you look at how you set the onChange of Button and Input, in one you use an arrow function for handleLoginClick and the other you use {this.handleEmailChange}.

The arrow function automatically binds this to the function. There are two ways to fix this. Either:

onChange = {this.handleEmailChange.bind(this)}

or

onChange = {(event) => handleEmailChange(event)}

This will create a binding between the function and the this that you are setting the state of.

Check out : Difference of .bind() to arrow function () => usage in React for more info on binding to context using arrow functions or .bind()

Tevon Strand-Brown
  • 1,283
  • 3
  • 16
  • 28