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

3
  • check this stackoverflow.com/questions/43893508/… Commented Dec 20, 2017 at 9:44
  • 1
    splice returns the removed items. splice first and then assign Commented Dec 20, 2017 at 9: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. Commented Dec 20, 2017 at 9:57

3 Answers 3

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)})
}
Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

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.

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.