Gaurav Soni Gaurav Soni - 2 months ago 14
React JSX Question

Unable to delete list item in react. Error shows: Uncaught TypeError: Cannot read property 'remove' of undefined

I'm trying to make simple todo app.In this i want delete item from list by onClick function. The button onClick returns function named remove(i) which deletes the item in list. But I'm getting error as mentioned above.
The code is as follows:

import React, { Component } from 'react';
import ReactDom from 'react-dom';
import logo from './logo.svg';
import './App.css';

class App extends Component {

constructor(){
super();
this.state={
todo:[]
};
};

entertodo(keypress){
var todo=this.refs.newtodo.value;
if( keypress.charCode == 13 )
{
this.setState({
todo: this.state.todo.concat(todo)
});
this.refs.newtodo.value=null;
};
};
todo(data,i){
return (
<li key={data.id} index={i}>
<input type="checkbox"className="option-input checkbox"/>
<div className="item">
{data}
<button onClick={this.remove.bind(this)}className="destroy"></button>
</div>

</li>
);
};
remove(i){
var todo=this.refs.newtodo.value;
var deletetodo=this.state.todo.concat(todo)
deletetodo.splice(i,1);
this.setState({todo:deletetodo})
};

render() {

return (
<div>
<div className="lines"></div>
<div>
<input type="text" ref= "newtodo" onKeyPress={this.entertodo.bind(this)}className="inputext"placeholder='todos'/>
</div>
<div className="app">

<ul>
{this.state.todo.map(this.todo.bind(this))}

</ul>
</div>
</div>
);
}
}

export default App;


The same problem arises if i try to call a function for to strikeoff the list item upon click on checkbox. Need help.

Answer

You need to bind your todo and remove function and also need to splice your todo array correctly. As your ref new is not defined and unique, you cannot access the value so just splice the array by index

class App extends React.Component {

  constructor(){
    super();
    this.state={
      todo:[]
    };
  };

  entertodo(keypress){
    var todo=this.refs.newtodo.value;
    if( keypress.charCode == 13 )
    {
      this.setState({
        todo: this.state.todo.concat(todo)
      });
      this.refs.newtodo.value=null;
    };
  };
  todo = (data,i) => {
    return (
      <li>
      <input type="checkbox"className="option-input checkbox"/>
      <div key={data.id} className="item">
      {data}
      <button onClick={this.remove.bind(this, i)}className="destroy">Delete</button>
      </div>

      </li>
    );
  };
  remove = (i) =>{
    var deletetodo = {...this.state.todo};
    this.state.todo.splice(i,1);
    this.setState({todo:this.state.todo})
  }; 


  render() {

    return (
      <div>
      <div className="lines"></div>
      <div>
      <input type="text" ref= "newtodo" onKeyPress={this.entertodo.bind(this)}className="inputext"placeholder='todos'/>
      </div>
      <div className="app">

      <ul>
      {this.state.todo.map(this.todo)}

      </ul>
      </div>
      </div>
    );
  }
}

ReactDOM.render(<App/>,document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>

<div id="app"></div>

Comments