0

I have managed to create a list using ReactJS where you type something in and it adds it to the list underneath the text box. However, I now want the user to be able to delete something from that list.

Here is some code:

var ToDoList = React.createClass({

  deleteItem: function(item){
    var items = this.state.items.filter(function(itm) {
      return item.id !== itm.id;
    })
  },

  render: function() {
    var DeleteClick=this.deleteItem;        
    var listItems = this.props.listItems.map(function(submittedValue) {
      return (
          <ToDoListItem key={submittedValue.id}>{submittedValue.text}<button onClick={DeleteClick}> X </button></ToDoListItem>

      )
    });
    return (
        <ul className="toDoList">
          {listItems}

        </ul>
    );
  }
});

This code generates this error message: Uncaught TypeError: Cannot read property 'deleteItem' of undefined

Here is some more code as to how I am generating the adding to the list:

var i = 1;
var ToDoForm = React.createClass({

  getInitialState: function() {
    return {text: '', submittedValues: [{id: '000001', text: 'Rich'}, {id: '000002', text: 'Simon'}]};
  },
  handleChange: function(event) {
    this.setState({text: event.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();

    var submittedValue = {text: this.state.text, id: i++};
    this.setState({submittedValues: this.state.submittedValues.concat(submittedValue)});
    this.setState({text: ''});
    console.log("ToDo: " + this.state.submittedValues);
  },

  render: function() {

    return (
        <div>
          <h1> todos </h1>

          <form className="todoForm" onSubmit={this.handleSubmit}>
            <input
                type="text"
                placeholder="Type out a task"
                value={this.state.text}
                onChange={this.handleChange}
                />
            <input
                type="submit"
                value="Submit todo"
                />
          </form>

          <h2> Data should appear here </h2>

          <ToDoList listItems={this.state.submittedValues}/>
        </div>
    );
  }
});

Not sure how to get the delete to work

4 Answers 4

1

You need set this to .map because this refers to global scope not to ToDoList object,

var listItems = this.props.listItems.map(function(submittedValue) {
   // your code
}, this);
Sign up to request clarification or add additional context in comments.

7 Comments

what needs to go inside the deleteItem function though?
@The Hurricane could you clarify what do you mean
sure. I have edited the code above to reflect what my code looks like including your changes. currently when I click on my button nothing happens when what I want is for it to delete that particular item. something must be wrong in my deleteItem function but I cannot work it out. can you see any errors?
@The Hurricane I've created example based on your code - jsfiddle.net/69z2wepo/22297.
couple of questions. 1) line 31 why no closing tag for ToDoListItem? 2) line 18 what does el stand for? 3) mine is looking like this: Rich onDelete=
|
1

you have to try the below mentioned code as:

var DeleteClick=this.deleteItem;
var listItems = this.props.listItems.map(function(submittedValue) {
  return (
      <ToDoListItem key={submittedValue.id}>{submittedValue.text}<button onClick={DeleteClick}> X </button></ToDoListItem>

  )
});

you have used this keyword in map function and scope of this is limited to map function only that's y it's causing the prob

5 Comments

cannot read properties items of null is the error presumably because the items variable has nothing in it
@TheHurricane: yes because you haven't set state in your ToDoList Component
what should be in that delete function then?
you should use this.props.listItems insted of this.state.items
actually whatever you have done in your child component do it in parent and apply the filter on state data once state changed it would automatically call the render method and your view updated
0

The context of this inside the map function does not reference the enclosing React class. In order to reference the React class using this inside the map function, pass this to the map function:

var listItems = this.props.listItems.map(fn, this)

Comments

0

If you're using ES6 - you can use Arrow functions for lexical binding. Also, the best way to handle adding/updating/deleting items in your list is to use Immutability helpers provided by React

var listItems = this.props.listItems.map( submittedValue => {
      <ToDoListItem key={submittedValue.id}>{submittedValue.text}<button onClick={this.deleteItem}> X </button></ToDoListItem>
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.