我有一个从app.js包装的表单,后者从那里接收道具以更新文件cadastro.js上的输入和按钮,但是当我单击“编辑注册”时,我的按钮更改从函数getDerivedStateFromProps编辑与描述不变。在单击按钮编辑两次后,它会更新。
但是,如果我在控制台上使用getDerivedStateFromProps函数进行调试,则会在正确的时间显示给我。我的代码有什么问题?
App.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;
Cadastrar.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;
Tabela.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;
答案 0 :(得分:0)
您没有从getDerivedStateFromProps
返回任何信息,而必须返回一个对象以更新状态
getDerivedStateFromProps
在初始安装和后续更新上都在调用render方法之前立即被调用。它应该返回一个对象以更新状态,或者返回null则不更新任何内容。
使用以下方法更改thegetDerivedStateFromProps``方法。返回一个对象而不是改变状态。
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);
中调用副作用componentDidUpdate
。
如果您需要因道具更改而产生副作用(例如,数据获取或动画),请改用componentDidUpdate生命周期。