2

I am using React to create a to do list app, in my app when I click x button to remove an Item and using console.log to check current array, I can see the array is updated correctly with the Item I want to remove removed from the list of array, but the Dom only renders the Item I want to remove instead of the whole array

import React from 'react';
import ReactDom from 'react-dom';

class TodoList extends React.Component{
    constructor(props){
        super(props);
        this.state={
            todoList:[],
            todo:''
        }
    };

    onValueChange=(e)=>{
        const todo=e.target.value;
        this.setState({todo})
    };

    removeItem=(props)=>{
        this.setState({todoList:this.state.todoList.splice(props,1)})
        console.log(this.state.todoList)
    };

    onSubmit=(e)=>{
        e.preventDefault();
        const {todoList,todo}=this.state
        this.setState({todoList:[...todoList,todo]})
        this.setState({todo:''})
        console.log(this.state.todoList)
    };

    render(){
        const myList=this.state.todoList.map((todo,index)=>(
            <li key={index}>
                {todo}
                <button onClick={()=>this.removeItem(index)}>x</button>
            </li>
        ))
        return (
            <div>
                <form onSubmit={this.onSubmit}>
                    <input 
                        type="text"
                        value={this.state.todo}
                        onChange={this.onValueChange}
                        autoFocus
                        placeholder='todo'
                    />
                </form>
                <ol>
                    {myList}
                </ol>
            </div>
        )
    };
};

ReactDom.render(<TodoList/>,document.getElementById('app'));

this is the picture

enter image description here

in the picture you can see that the console shows the array with item '5' removed, but the screen only show the item '5' instead of the items 1 to 4

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Nhat
  • 399
  • 3
  • 6
  • 22
  • check this https://stackoverflow.com/questions/43893508/remove-items-form-the-list-in-react-js/43893804#43893804 – Shubham Khatri Dec 20 '17 at 09:44
  • 1
    splice returns the removed items. splice first and then assign – cdoshi Dec 20 '17 at 09:46
  • dont check array with console.log! setState is async method and you cant see state mutation immediately after setState. You can use method like setTimeout(() => console.log(this.state)) or print state in componentDidUpdate function. – Igor S Dec 20 '17 at 09:57

3 Answers3

4

In React: mutating state directly is discouraged.

Best practice would be to clone using a spread and splice() the result.

removeItem = (index) => {
  return this.setState({todoList: [...this.state.todoList].splice(index, 1)})
}
Arman Charan
  • 5,669
  • 2
  • 22
  • 32
3

Fix your removeItem

removeItem = (props)=> {
    this.state.todoList.splice(props, 1)
    this.setState({todoList: this.state.todoList})
    console.log(this.state.todoList)
};

Array.prototype.splice() method modify the array in place.

Return Value

An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned.

Vipin Kumar
  • 6,441
  • 1
  • 19
  • 25
1

Splice function doesn't return you the final array, instead it mutates the array, on which the operation is being performed.

It is good if you extract todoList out of this.state and perform splice operation.

removeItem=(props)=>{
    const { todoList } = this.state;
    todoList.splice(props, 1);
    this.setState({
        todoList,
    });
    console.log(this.state.todoList)
};

The above answer just works fine. But this is just a cleaner implementation of the same.

Suhas V
  • 164
  • 6