Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

React: Button apagando dados na table

Bom dia,

Sou novo na programação e estou com o seguinte problema.

Tenho uma tabela que é gerado dinamicamente por uma API, essa table gera duas colunas ID e descrição, acrescentei mais uma coluna com um Button que seria criado para cada nova linha.

Estou tentando fazer com que o Button quando for clicado apague a sua respectiva linha da tabela e também apague na API.

Procurei em diversos lugares porem não consigo fazer funcionar, se alguém tiver alguma ideia de como resolver isso.

Obs: Tive dificuldades em colar o código no fórum, se faltar alguma coisa por favor me avise para que eu consiga explicar o máximo possível, pois estou a muitos dias com isso e não consigo avançar.

import React, { Component } from 'react';
import Server from './Server';
class App extends Component {
constructor() {
    super();
    this.state = {
        Produtos: [],
        Produto: '',
        Mensagem: ''

    }

}

componentWillMount() {
    axios.get(Server + `/produto/listar`)
        .then(
            (result) => {
                this.setState(result.data);
                if (this.state.Produtos.length > 0) {
                    this.setState({ Produto: this.state.Produtos[0] });
                }
            })
}

novo = () => {
    this.setState({ Produto: { "id": 0, "descricao": "Novo" } });
}

gravar = () => {
    if (this.state.Produto.descricao.length > 100) {
        this.setState({ Mensagem: 'Máximo de 100 posições.' });
        return;
    }
    if (this.state.Produto.id === 0) {
        this.inserir();
    } else {
        this.atualizar();
    }
    this.setState({ Mensagem: 's.' });
}

inserir = () => {
    const d = this.state.Produto.descricao;
    axios.get(Server + `/produto/inserir?descricao=${d}`)
        .then(
            (result) => {
                this.setState({ Produto: result.data });
                this.setState({ Produtos: [...this.state.Produtos, this.state.Produto] });
            })
}

atualizar = () => {
    const i = this.state.Produto.id;
    const d = this.state.Produto.descricao;
    axios.get(Server + `/produto/atualizar?id=${i}&descricao=${d}`)
        .then(
            (result) => {
                var i = this.state.Produtos.findIndex(x => x.id === this.state.Produto.id);
                this.setState({ Produto: result.data });
                var Produtos = [...this.state.Produtos];
                Produtos[i] = this.state.Produto;
                this.setState({ Produtos });
            });
}

 apagar = () => {
        if (this.state.Produto.id > 0) {
            var i = this.state.Produto.id;
            axios.get(Server + `/produto/apagar?id=${i}`)
                .then(
                    (result) => {
                        var i = this.state.Produtos.findIndex(x => x.id === this.state.Produto.id);
                        var Produtos = [...this.state.Produtos];
                        Produtos.splice(i, 1);
                        this.setState({ Produtos });
                        if (this.state.Produtos.length > 0) {
                            this.setState({ Produto: Produtos[0] });
                        }
                    });
        }
    }
 render() {
        const { Produtos, Produto, Mensagem } = this.state

        return (
 <div className={"col-3"}>
                                <button type="button" onClick={this.apagar} className="btn btn-danger">Apagar</button>
                            </div>
<table id="my_table" className="table table-hover table-responsive-md">
                    <thead>
                        <tr>
                            <th>Id</th>
                            <th>Descricao</th>
                            <th>Index</th>
                            <th>Ações</th>

                        </tr>
                    </thead>
                    <tbody>
                        {
                            Produtos.map((Produto, index) => { 

                                return (
                                    <tr key={index}>
                                        <td>{Produto.id}</td>
                                        <td>{Produto.descricao}</td>
                                        <td>{index}</td>
                                        <td>
                                            <button className="btn btn-danger" onClick={this.apagar}>Deletar</button>
                                            <button className="btn btn-render btn-warning " >Alterar</button>
                                        </td>
                                    </tr>
                                )
                            })
                        }
                    </tbody>
                </table>
1 resposta
solução!

Fala Denis, tudo bem ?

Tava dando uma olhada no código aqui, ainda tenho certas dúvidas sobre o funcionamento atual, mas vamos tentar.

A primeira duvida que tive foi como a function apaga consegue o id do produto selecionado. A função não recebe um id referente ao selecionado. Você pega a informação aparentemente do Produto, mas se olharmos o código da componentDidMount parece que ele é sempre o primeiro elemento [0] da lista.

Tente mudar a abordagem. Usando um id na função. Algo como:

apagar = (id) => {

        axios.get(Server + `/produto/apagar?id=${id}`)
            .then((result) => {
                //se tudo ocorreu bem com a requisição

                const novaLista = this.state.produtos.filter(produtoId => produtoId !== id); // filtra todos os elementos que não são o que foi excluído
                this.setState({produtos: novaLista});
            });
    }

Aí você dá um jeito de passar o id do produto na hora de passar a referencia da função, tipo onClick={() => this.apagar(produto.id)}. Essa abordagem pode te ajudar a minimizar o problema de gerir o estado da lista e mais a propriedade que representa um produto (Produto). Aliás eu acredito que você só precise da lista e da mensagem no estado do seu componente. Enfim...

Acho que isso deve ajudar. Abraço!