0

I've binded all of my methods in the constructor to my class. One of them is not working properly, the console logs an undefined error. It is executed in a function, but I previously declared it's this keyword as a class. I can not spot the problem. The handleRemove is the method, I'm talking about.

import React, { Component } from 'react';


class ToDoList extends Component {
  constructor(props) {
    super(props);
    this.state = {list: [], items: ''};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleRemove = this.handleRemove.bind(ToDoList);
  }

  handleChange(event) {
    this.setState({items: event.target.value})
    console.log(event.target.value);
  }

  handleSubmit(event) {
    this.setState({ list: [...this.state.list, this.state.items]})
    event.preventDefault();
  }

  handleRemove(event) {
    const filteredArray = this.state.list.filter(item => item !== event.target.value)
    this.setState({list: filteredArray});
  }



  render() {
    return (
    <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input onClick={this.handleSubmit}type="submit" value="Submit" />
      </form>
      <ul>
        {this.state.list.map(function(i, index){
          return(
            <li key={index}>{i}<button onClick={this.handleRemove}>X</button></li>
          )
        })}
      </ul>
      <p>Remaining: {this.state.list.length}</p>
      </div>
    );
  }
}

export default ToDoList;
  • this.handleRemove = this.handleRemove.bind(ToDoList); should be this.handleRemove = this.handleRemove.bind(this); – Ved Apr 20 '17 at 17:24
  • Possible duplicate of [Detecting an undefined object property](http://stackoverflow.com/questions/27509/detecting-an-undefined-object-property) –  Apr 23 '17 at 23:21

2 Answers2

1

You are binding the method to the class, not the instance - the class does not have a static method named handleRemove, and even if it did - you can not access this within a static method; therefore this will not work:

this.handleRemove = this.handleRemove.bind(ToDoList);

Change to:

this.handleRemove = this.handleRemove.bind(this);
Rob M.
  • 35,491
  • 6
  • 51
  • 50
0

Two things:

First, in your constructor, bind this and not ToDoList.

this.handleRemove = this.handleRemove.bind(this);

Second, functions are scoped, so inside the .map this is not the component. You can fix that by using an arrow function (or alternatively using .bind(this)):

{this.state.list.map((i, index) => (
  <li key={index}>{i}<button onClick={this.handleRemove}>X</button></li>
))}
Fabian Schultz
  • 18,138
  • 5
  • 49
  • 56
  • Thx Fabian, I just experimented with the this in the constructor and accidentally left the class as the this keyword, but now, it's working, I did not know about that the arrow functions will not create their own execution context. –  Apr 20 '17 at 17:37
  • Yes, it should work initially with the class name but you won't be able to delete a task. If my answer solved your problem, click the big checkbox to accept it as the answer. – Fabian Schultz Apr 20 '17 at 17:38