3
respostas

Erro ao tentar remover item da tabela

Boa noite ao tentar remover um item de um componente Table que eu criei recebo o seguinte erro: Uncaught Error: Objects are not valid as a React child (found: object with keys {text}). If you meant to render a collection of children, use an array instead. Alguém poderia me explicar o porque desse erro e porque ele só acontece quando tento remover uma tarefas de uma tabela que possui mais de uma linha ? Segue o código:

import React from 'react';
import 'materialize-css/dist/css/materialize.min.css'
import './header.css';
import Header from './Components/Header';
import Form from './Components/Form';


// const data;

function App() {

    return (
      <div>

        <Header/>
        <Form/>

      </div>
    );
}

  export default App;

import React, { Component, Fragment } from 'react';
import Table from './Table';

class Form extends Component{

    constructor(props){
        super(props);

        this.state = {
            tarefa: "",
            lista: []
        }

        this.addItem = this.addItem.bind(this);
        this.removeItem = this.removeItem.bind(this);
    }

    addItem(event){

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

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

            state.lista.push({ text: this._tarefaInput.value });
            this.setState(state);
        }


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

        console.log(this.state.lista);

    }

    removeItem(index){

        const {lista} = this.state;

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


    }

    render(){
        return(
            <Fragment>
                <div className="row">
                    <form className="col s6" onSubmit={this.addItem}>
                        <div className="row">
                            <div className="input-field col s6">
                                <br/>
                                <input placeholder="Insira a tarefa do dia" value= {this.state.tarefa} id="todo" 
                                    onChange={(e) => this.setState({tarefa: e.target.value})} 
                                        ref={event => this._tarefaInput = event} type="text" className="validate"/>

                                <label htmlFor="todo">Minhas Tarefas</label>
                            </div>
                        </div>

                        <div>
                            <button className="btn waves-effect waves-light" type="submit" name="action">Submit
                                <i className="material-icons right">send</i>
                            </button>
                        </div>

                        {/* {this.state.tarefa} */}
                        {this.state.lista}
                    </form>
                </div>


                <Table lista= {this.state.lista} removeItem = {this.removeItem}/>

            </Fragment>
        )
    }
}

export default Form;

insira seu código aqui

import React, { Component } from 'react'

const Thead = () => {
    return( 
        <thead>
          <tr>
              <th>Tarefas</th>
              <th>Excluir</th>
          </tr>
        </thead>
    );
}

const Tbody = props => {

    let linhas = props.lista.map((item, index) => {
        return(

            <tr key={index}>
                <td>{item.text}</td>
                <td><a onClick ={() => props.removeItem(index)} className="waves-effect waves-light btn-small"><i className="material-icons left">delete</i>Remover</a></td>
            </tr>
        );
    });


    return(
        <tbody>{linhas}</tbody>
    );
}

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

        // this.state = {

        // }
    }

    render(){
        return(
            <table>
                <Thead/>
                <Tbody lista = {this.props.lista} removeItem = {this.props.removeItem}/>
            </table>
        );
    }


}

export default Table
3 respostas

Oi, Rafael, tudo bem?

Testando essa forma, consegui remover:

<a onClick={() => props.removeItem(index)}>Remover</a>

Mas acho mais interessante utilizar a tag button à tag a, pois quando vamos adicionar, remover, editar, a tag de botão faz mais sentido do que a tag âncora que é usada para links.

Testa agora e fala se deu certo :}

Boa tarde Lais ! então aquele delete está envolvido por uma tag para apenas mostrar o icone de uma lixeira. Eu estava testando e só funciona quando removemos o primeira tarefa da lista se adicionar mais verá que da esse erro que relatei logo acima. alterei a minha função addItem para está abaixo e funcionou de uma olhada

    addItem(event){

        let {lista} = this.state;
        event.preventDefault();

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

            // lista.push(...lista);
            // lista.push({text: this._tarefaInput.value});
            this.setState({lista:[...lista, this._tarefaInput.value]});
        }


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

        console.log(this.state.lista);

    }

Quero saber porque do outro jeito que estava não funcionou e desse outro jeito sim. O método setState() não deixa eu adicionar objetos daquela forma dentro dele?

Áh e obrigado pela dica já alterei a tag ancor para button ! Por favor se puder me explicar, porque como sou iniciante em react não quero travar nesses erros triviais. Desde agradeço...

Oi, Rafael, tudo bem?

Entendi. Então, vamos entender melhor o porquê da primeira forma não ter dado certo.


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

        if(this._tarefaInput.value !== ""){
            state.lista.push({ text: this._tarefaInput.value });
            this.setState(state);
        }
        this.setState({tarefa: ""});
        console.log(this.state.lista);
    }

No seu método addItem você está editando diretamente o estado da função com o push, em React isso leva a comportamentos inesperados, como o que ocorre, que é o de apagar somente o primeiro da lista, quando tentamos apagar outros, não conseguimos.

A segunda forma, em que o comportamento dá certo, você cria a lista, usa o spread operator para criar uma cópica da lista, depois usa o push para addionar os elementos na nova lista e, aqui this.setState você atualiza o estado, ou seja, você não muda diretamente.

E sim, a tag button é melhor mesmo :}

Se ficou alguma dúvida é só falar!