0
votes

I am trying to build a simple todolist app on react and I came up this problem. I could write the code necessary for adding todo items to the list defined in the state and displaying it but when it comes to deleting items off of the list from the click of the button adjacent to every todoitem, all todoitems get removed from the list except the first item. what should I do. Here's the code :

The TodoList(parent) Component:

import React, {Component} from 'react';
import AddTodos from './AddTodos';
import DisplayTodos from './DisplayTodos'
import "./TodoList.css";


class TodoList extends Component {
    constructor(props){
        super(props);
        this.state = {
            myList: [],
            searchField: ''
        }
        this.DeleteTodos = this.DeleteTodos.bind(this)
    }

    onSearchChange = (event) => {   
    this.setState({searchField: event.target.value})

}


    addTodo = () => {

        if(this.state.searchField !=="") {
        var newItem = {
            text: this.state.searchField,
            key: Date.now()
        }

        this.setState({myList: this.state.myList.concat(newItem)})
        this.setState({searchField: ""})
        console.log(this.state.myList)

        } else{
            alert("Please enter something")
        }

    }

    DisplayList = () => {
        const ListItems = this.state.myList.map((listitem, i) => {
            return(
                <li key={listitem.key} onClick={(i) => this.DeleteTodos(i)}>{listitem.text} <button>Delete</button>
                </li>
                )
        })

        return ListItems;
    }

    DeleteTodos = (i) => {
        i.preventDefault()
        this.setState({myList: this.state.myList.splice(i, 1)})
    }


    render() {
        return(
            <div className="TodoList">
                <AddTodos addTodo={this.addTodo} onSearchChange={this.onSearchChange}/>
                <DisplayTodos DisplayList={this.DisplayList}/>
            </div>
            )
    }
}

export default TodoList;

The DisplayTodos Component:

import React, {Component} from 'react';
import AddTodos from './AddTodos';
import DisplayTodos from './DisplayTodos'
import "./TodoList.css";


class TodoList extends Component {
    constructor(props){
        super(props);
        this.state = {
            myList: [],
            searchField: ''
        }
        this.DeleteTodos = this.DeleteTodos.bind(this)
    }

    onSearchChange = (event) => {   
    this.setState({searchField: event.target.value})

}


    addTodo = () => {

        if(this.state.searchField !=="") {
        var newItem = {
            text: this.state.searchField,
            key: Date.now()
        }

        this.setState({myList: this.state.myList.concat(newItem)})
        this.setState({searchField: ""})
        console.log(this.state.myList)

        } else{
            alert("Please enter something")
        }

    }

    DisplayList = () => {
        const ListItems = this.state.myList.map((listitem, i) => {
            return(
                <li key={listitem.key} onClick={(i) => this.DeleteTodos(i)}>{listitem.text} <button>Delete</button>
                </li>
                )
        })

        return ListItems;
    }

    DeleteTodos = (i) => {
        i.preventDefault()
        this.setState({myList: this.state.myList.splice(i, 1)})
    }


    render() {
        return(
            <div className="TodoList">
                <AddTodos addTodo={this.addTodo} onSearchChange={this.onSearchChange}/>
                <DisplayTodos DisplayList={this.DisplayList}/>
            </div>
            )
    }
}

export default TodoList;

AddTodos Component

import React, {Component} from 'react';
import AddTodos from './AddTodos';
import DisplayTodos from './DisplayTodos'
import "./TodoList.css";


class TodoList extends Component {
    constructor(props){
        super(props);
        this.state = {
            myList: [],
            searchField: ''
        }
        this.DeleteTodos = this.DeleteTodos.bind(this)
    }

    onSearchChange = (event) => {   
    this.setState({searchField: event.target.value})

}


    addTodo = () => {

        if(this.state.searchField !=="") {
        var newItem = {
            text: this.state.searchField,
            key: Date.now()
        }

        this.setState({myList: this.state.myList.concat(newItem)})
        this.setState({searchField: ""})
        console.log(this.state.myList)

        } else{
            alert("Please enter something")
        }

    }

    DisplayList = () => {
        const ListItems = this.state.myList.map((listitem, i) => {
            return(
                <li key={listitem.key} onClick={(i) => this.DeleteTodos(i)}>{listitem.text} <button>Delete</button>
                </li>
                )
        })

        return ListItems;
    }

    DeleteTodos = (i) => {
        i.preventDefault()
        this.setState({myList: this.state.myList.splice(i, 1)})
    }


    render() {
        return(
            <div className="TodoList">
                <AddTodos addTodo={this.addTodo} onSearchChange={this.onSearchChange}/>
                <DisplayTodos DisplayList={this.DisplayList}/>
            </div>
            )
    }
}

export default TodoList;
1

1 Answers

0
votes
DeleteTodos = (i) => {
    i.preventDefault();
    let arr = [].concat(this.state.myList);
    arr.splice(i, 1);
    this.setState({myList: arr});
}

The splice function will change the array and return a new array of deleted items, so you should declair a variable to copy myList, and change the variable. What you do will change the state.