user1775718
user1775718

Reputation: 1578

React component `this` is not defined when handlers are called

I'm attaching a simple handler in JSX. Unless I do .bind(this) in the JSX, when I go into the change method, to do this.setState(), this is undefined. Am I doing something wrong??

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import CounterConstants from './../constants/constants';
import AppDispatcher from './../dispatcher/AppDispatcher';
import CounterActions from './../actions/actions';

class Controls extends Component {
  constructor(props) {
    super(props);
    this.state = {
      todoText: ''
    };
  }
  change(event){
    this.setState({todoText: event.target.value});
  }
  submit(event){
    if(this.state.todoText !== ''){
      CounterActions.addTodo({text: this.state.todoText});
      this.setState({todoText: ''});
    }
  }
  render(){
    return (
      <div className="controls form-inline">
        <input type="text" name="todoText" className="form-control" onChange={this.change.bind(this)} value={this.state.todoText} />
        <button className="btn btn-primary" onClick={this.submit.bind(this)}>Add a todo</button>
      </div>
    )
  }
}

export default Controls;

Upvotes: 1

Views: 997

Answers (2)

Felix Kling
Felix Kling

Reputation: 816364

Am I doing something wrong?

No, that's how JavaScript works. Functions are not auto-bound. The value of this depends on how a function is called. So if you pass a function somewhere but need this to have a specific value, you have to bind it yourself (note: where you bind the function doesn't matter).

Simplified example (using an object):

'use strict';

var obj = {
  method() {
    console.log(this);
  },
};

var method = obj.method;
var boundMethod = obj.method.bind(obj);
method();      // undefined
boundMethod(); // Object {}
obj.method();  // Object {}

Related:

Documentation:

Upvotes: 2

Elod Szopos
Elod Szopos

Reputation: 3526

Since you are using es6 classes (class Controls extends Component), functions will not be auto-bound for you. In order to provide your functions with context, you need to bind the value of this to the context of your component.

If you were to use the React.createClass, then all functions would be auto-bound for you by default.

Most people use the constructor to bind their functions to the context of this. It's a little cleaner than cluttering up the JSX.

Hope that helps.

Upvotes: 2

Related Questions