Laura
Laura

Reputation: 99

Why my setState doesn't accept this object?

I'm working in a to-do list on React and when method deleteItemis called, I get Uncaught Error: Objects are not valid as a React child (found: object with keys {text}) but I don't understand the reason

class Form extends Component{
    constructor(props){
        super(props);

        this.state = {
            task: "",
            list: []
        }

        this.saveItem = this.saveItem.bind(this);
        this.deleteItem = this.deleteItem.bind(this);
    }

    saveItem(event){

        let state = this.state;
        event.preventDefault();

        if(this._taskInput.value !== ""){

            state.list.push({ text: this._taskInput.value });
            this.setState(state);
        }

        this.setState({task: ""});

    }

    deleteItem(index){

        const {list} = this.state;

        this.setState({
            list: list.filter((item,itemCurrent) => {
                // console.log(item.key, index);
                return (itemCurrent !== index);
            }),
        });


    }

render(){
        return(
            <Fragment>
                    <form  onSubmit={this.saveItem}>

                                <input value= {this.state.task} id="to-do" 
                                    onChange={(e) => this.setState({task: e.target.value})} 
                                        ref={event => this._taskInput = event} type="text" className="validate"/>

                                <label htmlFor="to-do">My tasks</label>
                            </div>

                            <button  type="submit" name="action">Submit
                                
                            </button>
                        </div>

                        {{this.state.task}}
                        {this.state.list}
                    </form>
                </div>
                <Table list= {this.state.list} deleteItem = {this.deleteItem}/>
        

Upvotes: 0

Views: 69

Answers (2)

brein
brein

Reputation: 1419

first of all there's a big conceptual error here:

  if (this._tarefaInput.value !== ""){
    state.list.push({ text: this._taskInput.value });
    this.setState(state);
  }

you are directly editing the state with that push function, you should never do this in react as it will lead to unexpected consequences, this is how you should update the state:

  if (this._tarefaInput.value !== ""){
    //use the spread operator (...) to create a copy of the list in the state
    const newList = [... state.list];
    // push the new element tot the new list
    newList.push({ text: this._taskInput.value });
    // update the state
    this.setState({list: newList});
  }

Now the error you are getting is likely happening because somewhere in your code (possibly inside <Table/>) you are trying to print each element of the list array as a react component. You haven't shared the part where the list is rendered, but I'm guessing you are doing something like this:

//somewhere inside a render:

{
  list.map(Element => <Element />);
}

//Proper way of doing it

{
  list.map(element => <p>{element.text}</p>);
}

I can try to help more if you share more of your code and the entitre log with the the error description (with file and line number)

Upvotes: 1

jme11
jme11

Reputation: 17374

The issue is this line inside your render: {this.state.list}. You can render an array, but you can't render an object. The solution is to map over the array and output some JSX such as the following. Let's assume you have a list of objects with a name and id property:


  {this.state.list.map(item => (<div key={item.id}>{item.id}</div>))}

Upvotes: 1

Related Questions