Когда я нажимаю кнопку, чтобы изменить свое значение, состояние не обновляет введенное значение - PullRequest
0 голосов
/ 22 января 2020

У меня есть форма, обернутая из приложения. js, которые получают оттуда реквизиты для обновления моих входов и кнопок в файле кадастра. js, но когда я нажимаю на кнопку "Изменить", меняют кнопку, чтобы редактировать из моего Функция getDerivedStateFromProps мой ввод с описанием не меняется. Он просто обновляется после того, как я дважды щелкну на кнопке edit.

Но если я отлаживаю на консоли в функции getDerivedStateFromProps, покажи мне в нужное время. В чем проблема с моим кодом?

Приложение. js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Cadastrar from "./components/Cadastrar";
import Tabela from "./components/Tabela";

class App extends Component {

    state = {
        update: '',
        idTamanhoEditar: ''
    }


    editarRegistro = (idRegistroEditarTabela) => {
        this.setState({idTamanhoEditar: idRegistroEditarTabela})
    }

    updateTabela = (atualizarTabela) => {
        this.setState({update: atualizarTabela})
    }

    render() {
        return(
            <div>
                <Cadastrar atualizarTabela={this.updateTabela} editarFromParent={this.state.idTamanhoEditar}/>
                <Tabela editarRegistro={this.editarRegistro} updateFromParent={this.state.update} />
            </div>
        )
    }

}

export default App;

Кадастр. js

import React, { Component } from 'react';
import './Cadastrar.css';
import axios from "axios";

class Cadastrar extends Component {

    constructor(props) {
        super(props);
        this.state = {
            tamanho: {
                id: '',
                descricao: '',
            },
            error: '',
            sucess: '',
            tipoAcao: 'Cadastrar'
        };

        this.atualizaDados      = this.atualizaDados.bind(this);
        this.cadastrar          = this.cadastrar.bind(this);

    }

    atualizaDados(e) {
        let tamanho = this.state.tamanho;
        tamanho[e.target.name] = e.target.value;

        this.setState({tamanho: tamanho});

    }

    cadastrar(e) {

        const {tamanho} = this.state;
        if(tamanho.descricao !== '') {
            axios.post(`http://localhost/react-project/src/api/register.php`, { descricao: tamanho.descricao })
                .then(res => {
                    if(res.data === 'sucess') {
                        this.setState({tamanho:{id:'', descricao: ''}})
                        //Tabela.atualizarItensTabela();
                        this.setState({sucess: 'Cadastro efetuado com sucesso!', error: ''})
                        this.props.atualizarTabela(true);
                    }
                })
        } else {
            this.setState({error: 'Preencha o campo descrição!', sucess: ''})
        }

        e.preventDefault();
    }

    static getDerivedStateFromProps(props, state) {


        if(props.editarFromParent !== state.tamanho.id  ) {
            console.log("Entrou");

            state.tamanho.id = props.editarFromParent;
            state.tipoAcao = 'Atualizar';
            state = Cadastrar.consultarTamanho(state.tamanho.id, state);

        }

        return null;
    }

    static consultarTamanho(idTamanho, state) {

        axios.post(`http://localhost/react-project/src/api/consult.php`, { id: idTamanho })
            .then(res => {
                if(res.data.descricao) {
                    state.tamanho.descricao = res.data.descricao;
                }
            })

        return state;
    }

    render() {
        return (
            <div id='formulario-de-cadastro' className='container'>
                <div className='page-header'>
                    <h2 className='titulo-cadastrar-tamanho'>Cadastrar Tamanho</h2>
                </div>
                <form onSubmit={this.cadastrar}>
                    <input type='hidden' name='id' value={this.state.tamanho.id} onChange={ this.atualizaDados } /><br/>
                    <div className='form-group'>
                        <label htmlFor='descricao'>Descrição</label>
                        <input type='text' className='form-control' name='descricao' id='descricao' onChange={ this.atualizaDados } value={this.state.tamanho.descricao} /><br/>
                        <button type='submit' className='btn btn-primary'>{this.state.tipoAcao}</button>
                        <button type='submit' className='btn btn-danger ml-1'>Cancelar</button>
                    </div>
                </form>
                {this.state.error && <p className='alert alert-warning'>{this.state.error}</p>}
                {this.state.sucess && <p className='alert alert-success'>{this.state.sucess}</p>}
            </div>
        );
    }
}

export default Cadastrar;

Табела. js

import React, { Component } from 'react';
import axios from 'axios';

import './Tabela.css';

class Tabela extends Component {

    constructor(props) {
        super(props);
        this.state = {
            tamanhos: [],
            tamanho: {
                id: '',
                descricao: ''
            },
        }

        this.apagarTamanho = this.apagarTamanho.bind(this);
        this.atualizarItensTabela = this.atualizarItensTabela.bind(this);

    }

    componentDidMount() {
        this.atualizarItensTabela();
    }

    atualizarItensTabela() {
        let url = 'http://localhost/react-project/src/api/consultAll.php';

        fetch(url)
            .then((r) => r.json())
            .then((json) => {
                this.setState({tamanhos: json});
            });
    }

    apagarTamanho(e, idTamanho) {

        e.preventDefault();

        axios.post(`http://localhost/react-project/src/api/delete.php`, { id: idTamanho })
            .then(res => {
                if(res.data === 'sucess') {
                    this.atualizarItensTabela();
                }
            })
    }

    editarTamanho(e, idTamanho) {
        this.props.editarRegistro(idTamanho);

        e.preventDefault();
    }

    render() {
        return (
            <div className='container mt-5'>
                {this.props.updateFromParent && this.atualizarItensTabela()}
                <table id='tabela-tamanhos' className='table table-hover'>
                    <thead>
                        <tr>
                            <th scope="col">Código</th>
                            <th scope="col">Descrição</th>
                            <th scope="col">Ações</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.tamanhos.map(
                            tamanho=>
                                <tr key={tamanho.id} className='row-tamanho'>
                                    <th scope="row">{tamanho.id}</th>
                                    <td>{tamanho.descricao}</td>
                                    <td>
                                        <button className='btn btn-primary mr-1' onClick={(e)=>this.editarTamanho(e, tamanho.id)}>Editar</button>
                                        <button className='btn btn-danger' onClick={(e)=>this.apagarTamanho(e, tamanho.id)}>Apagar</button>
                                    </td>
                                </tr>
                        )}
                    </tbody>
                </table>
            </div>
        );
    }

}

export default Tabela;

1 Ответ

0 голосов
/ 22 января 2020

Вы ничего не возвращаете из getDerivedStateFromProps вам нужно вернуть объект для обновления состояния

getDerivedStateFromProps вызывается непосредственно перед вызовом метода рендеринга, как при первоначальном монтировании, так и при последующие обновления. Он должен возвращать объект для обновления состояния или ноль для обновления ничего.

Измените метод getDerivedStateFromProps `` с помощью приведенного ниже. Возвратите объект, скорее мутируя состояние.

 state = Cadastrar.consultarTamanho(state.tamanho.id, state);
    if (props.editarFromParent !== state.tamanho.id) {
      console.log("Entrou");
      return {
        tamanho: {
          id: props.editarFromParent,
          descricao: '',
        },
        error: '',
        sucess: '',
        tipoAcao: 'Atualizar'
      }
    }
    return null;

И вызовите побочный эффект state = Cadastrar.consultarTamanho(state.tamanho.id, state); in componentDidUpdate.

Если вам нужно выполнить побочный эффект (например, (извлечение данных или анимация) в ответ на изменение реквизита вместо этого используйте жизненный цикл componentDidUpdate.

...