ReactJS状态更新落后一步



我正在尝试使用ReactJS创建一个简单的表来显示用户信息。以下是一般代码结构的样子:

class ParentComponent extends React.Component {
state = { 
data : [] 
}
componentDidMount() {
// initializes state with data from db
axios.get("link/").then(res => {
this.setState({data: res.data});
});
// I should be able to call this.getData() instead
// of rewriting the axios.get() function but if I do so,
// my data will not show up
}

// retrieves array of data from db
getData = () => {
axios.get("link/").then(res => {
this.setState({data: res.data});
});
}  
render() {
return (
<div>
<ChildComponent data={this.state.data} refetch={this.getData} />
</div>
)
}
}

每个生成的行都应该有一个删除功能,我将根据给定的id从数据库中删除条目。删除后,我想从父组件中检索最新的数据,以便再次显示。

class ChildComponent extends React.Component {
// deletes the specified entry from database
deleteData = (id) => {
axios.get("deleteLink/" + id).then(res => {
console.log(res);
// calls function from parent component to 
// re-fetch the latest data from db
this.props.refetch();
}).catch(err => {console.log(err)});
}
render() {
let rows = null;
if(this.props.data.length) {
// map the array into individual rows
rows = this.props.data.map(x => {
return (
<tr>
<td>{x.id}</td>
<td>{x.name}</td>
<td>
<button onClick={() => {
this.deleteData(x.id)
}}>
Delete
</button>
</td>
</tr>
)
})
}
return (
<div>
<table>
<thead></thead>
<tbody>
{rows}
</tbody>
</table>
</div>
)
}
}

我在这里遇到的两个问题是:

  1. 从逻辑上讲,我应该能够从componentDidMount((中调用this.getData((,但如果我这样做,表就不会加载
  2. 每当我试图删除一行时,即使该条目已从数据库中删除,表也不会反映更新。只有当我刷新页面或删除另一行时,表才会更新。问题是,组件总是滞后1次更新

到目前为止,我已经尝试过:

  1. this.forceUpdate()-不工作
  2. this.setState({})-空的setState也不起作用
  3. 将CCD_ 3改变为CCD_;达到最大深度";或者类似的东西
  4. 在axios前面添加async等待-不起作用

如有任何帮助,我们将不胜感激。提前谢谢。


EDIT:我进行了一些调试并找到了与我的问题无关的问题。我的deleteData()位于ChildComponent中,它使用axios.post()而不是我忽略的axios.get()

deleteData = (id) => {
axios.post("deleteLink/", id).then(res => {
console.log(res);
// calls function from parent component to 
// re-fetch the latest data from db
this.props.refetch();
}).catch(err => {console.log(err)});
}

为了使axios.post()返回响应,为了执行.then(),您需要在路由代码中添加一个res.json()

您应该将数据映射到您的孩子中。

像这样改变你的父母:

class ParentComponent extends React.Component {
state = { 
data : [] 
}
componentDidMount() {
this.getData();
}

getData = () => axios.get("link/").then(res => this.setState({data: res.data});

deleteData = (id) => axios.get("deleteLink/" + id).then(res => this.getData())
.catch(err => { console.log(err) });
render() {
return (
<div>
<table>
<thead></thead>
<tbody>
{this.state.data.map(x => <ChildComponent row={x} deleteData={this.deleteData} />)}
</tbody>
</table>
</div>
)
}
}

你的子组件应该像这个

const ChildComponent = ({row,deleteData}) => (
<tr>
<td>{row.id}</td>
<td>{row.name}</td>
<td><button onClick={() => deleteData(row.id)}>Delete</button></td>
</tr >
)

我在你的代码中找不到问题,我能提供帮助的唯一方法就是告诉你我将如何调试它。

像这样编辑父级:

class ParentComponent extends React.Component {
state = { 
data : [] 
}
componentDidMount() {
// You are right when you say this should works, so 
// stick to it until the bug is fixed

console.log("parent mounted");
this.getData();
}

// retrieves array of data from db
getData = () => {
console.log("fetching data");
axios.get("link/").then(res => {
console.log("fetched data", res.data);
this.setState({data: res.data});
});
}  
render() {
return (
<div>
<ChildComponent 
data={this.state.data}
refetch={this.getData}
/>
</div>
)
}
}

在子组件中添加这两种生命周期方法只是为了调试目的:

componentDidMount () {
console.log("child mounted", this.props.data)     
}
componentDidUpdate (prevProps) {
console.log("old data", prevProps.data);
console.log("new data", this.props.data);
console.log("data are equal", prevProps.data === this.props.data);
}

如果你能分享日志,我可以试着帮助你更多的

最新更新