Building a Simple Todo List App in React


#62

Nevermind, I got the remove items functioning right. I just had to change some errors I made on the declaration of the props and it worked!


#63

Those errors can be tricky to identify and fix. Glad you got it sorted out :slight_smile:


#64

Need help pls. I followed through with the tutorial but encountered the following issue:

I have checked that the delete props are defined. In my TodoList, I already have:
this.addItem = this.addItem.bind(this);
this.deleteItem = this.deleteItem.bind(this);


#65

Can you post your full code? I’m curious to know what is going on in more detail :slight_smile:


#66

Hi kirupa,
Thanks for the quick response! Here’s my full code:

TodoItems.js:

import React, { Component } from "react";
 
class TodoItems extends Component {

  constructor(props) {
    super(props);
    this.delete = this.delete.bind(this);
  }

  delete(key) {
    this.props.delete(key);
  }

  createTasks(item) {
    return <li onClick={() => this.delete(item.key)} 
    key={item.key}>{item.text}</li>
  }
 
  render() {
    var todoEntries = this.props.entries;
    var listItems = todoEntries.map(this.createTasks);
 
    return (
      <ul className="theList">
          {listItems}
      </ul>
    );
  }
};
 
export default TodoItems;

TodoList.js:

import React, { Component } from "react";
import TodoItems from "./TodoItems";
import "./TodoList.css";
 
class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
    this.addItem = this.addItem.bind(this);
    this.deleteItem = this.deleteItem.bind(this);
  }
  addItem(e) {
    if (this._inputElement.value !== "") {
      var newItem = {
        text: this._inputElement.value,
        key: Date.now()
      };
   
      this.setState((prevState) => {
        return { 
          items: prevState.items.concat(newItem) 
        };
      });
      this._inputElement.value = "";
    }
     
    console.log(this.state.items);
       
    e.preventDefault();
  }

  deleteItem(key) {
    var filteredItems = this.state.items.filter(function (item) {
      return (item.key !== key);
    });
   
    this.setState({
      items: filteredItems,
    });
  }

  render() {
    return (
      <div className="todoListMain">
        <div className="header">
          <form onSubmit={this.addItem}>
            <input ref={(a) => this._inputElement = a} placeholder="enter task">
            </input>
            <button type="submit">add</button>
          </form>
        </div>
        <TodoItems entries={this.state.items} delete={this.deleteItem}/>
      </div>
    );
  }
}
 
export default TodoList;

#67

Your code is being treated as formatting by the response, so lines are getting swallowed up. Can you paste your code, highlight it, and hit the </> code formatting button? :slight_smile:

It is the fifth button from the left when composing a message:

EDIT: Nevermind! You made the change as I was composing this haha. Taking a look.


#68

Ok… Here it is… :slight_smile:

TodoItems.js:

import React, { Component } from "react";
 
class TodoItems extends Component {

  constructor(props) {
    super(props);
    this.delete = this.delete.bind(this);
  }

  delete(key) {
    this.props.delete(key);
  }

  createTasks(item) {
    return <li onClick={() => this.delete(item.key)} 
    key={item.key}>{item.text}</li>
  }
 
  render() {
    var todoEntries = this.props.entries;
    var listItems = todoEntries.map(this.createTasks);
 
    return (
      <ul className="theList">
          {listItems}
      </ul>
    );
  }
};
 
export default TodoItems;

TodoList.js

import React, { Component } from "react";
import TodoItems from "./TodoItems";
import "./TodoList.css";
 
class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
    this.addItem = this.addItem.bind(this);
    this.deleteItem = this.deleteItem.bind(this);
  }
  addItem(e) {
    if (this._inputElement.value !== "") {
      var newItem = {
        text: this._inputElement.value,
        key: Date.now()
      };
   
      this.setState((prevState) => {
        return { 
          items: prevState.items.concat(newItem) 
        };
      });
      this._inputElement.value = "";
    }
     
    console.log(this.state.items);
       
    e.preventDefault();
  }

  deleteItem(key) {
    var filteredItems = this.state.items.filter(function (item) {
      return (item.key !== key);
    });
   
    this.setState({
      items: filteredItems,
    });
  }

  render() {
    return (
      <div className="todoListMain">
        <div className="header">
          <form onSubmit={this.addItem}>
            <input ref={(a) => this._inputElement = a} placeholder="enter task">
            </input>
            <button type="submit">add</button>
          </form>
        </div>
        <TodoItems entries={this.state.items} delete={this.deleteItem}/>
      </div>
    );
  }
}
 
export default TodoList;

#69

Hi Kirupa,
I think I found the reason for the error:
Under TodoItem.js, I should change this

  constructor(props) {
    super(props);
    this.delete = this.delete.bind(this);

to

constructor(props) {
super(props);
this.createTasks = this.createTasks.bind(this);

Thanks so much for looking into this :smile:


#70

Your timing is scarily good haha. I was about to post the same thing. I have updated the tutorial to mention this. The version on Github also has the correct line of code: https://github.com/kirupa/kirupa/blob/master/reactjs/todolist/src/TodoItems.js