我有React JS应用,该应用使用ASP .NET Core Web API中的条目更新boostrap网格表。
并且我需要在插入后用新条目更新网格。我是在componentDidUpdate()
的帮助下并在那里使用refreshList()
函数的,但是我正在获得refreshList()
函数的无限循环。
关于如何在没有循环的情况下更新网格的任何想法?
import React, {Component} from 'react';
import {Table, Container} from 'react-bootstrap';
import {Button, ButtonToolbar} from 'react-bootstrap';
import {AddDepModal} from './AddDepModal';
import {EditDepModal} from './EditDepModal';
export class Department extends Component {
constructor(props){
super(props);
this.state = {deps:[], addModalShow: false, editModalShow: false}
}
componentDidMount()
{
this.refreshList();
}
refreshList()
{
fetch("https://localhost:5001/api/departments")
.then(response=> response.json())
.then(data=> {
this.setState({deps:data});
});
}
componentDidUpdate()
{
this.refreshList();
}
render(){
const {deps, depid, depname} = this.state;
let addModalClose = () => this.setState({addModalShow:false})
let editModalClose = () => this.setState({editModalShow:false})
return (
<div>
<Table className = "mt-4" striped bordered hover size ="sm">
<thead>
<tr>
<th>DepartmentID</th>
<th>DepartmentName</th>
<th>Options</th>
</tr>
</thead>
<tbody>
{deps.map(dep=>
<tr key = {dep.id}>
<td>{dep.id}</td>
<td>{dep.name}</td>
<td>
<ButtonToolbar>
<Button
className ="mr-2" variant ="info"
onClick = {() => this.setState({editModalShow:true, depid: dep.id, depname: dep.name})}
>
Edit
</Button>
<EditDepModal
show = {this.state.editModalShow}
onHide = {editModalClose}
depid = {depid}
depname = {depname}/>
</ButtonToolbar>
</td>
</tr>
)}
</tbody>
</Table>
<ButtonToolbar>
<Button variant = "primary" onClick = {() => this.setState({addModalShow: true})}>Add Department</Button>
<AddDepModal
show ={this.state.addModalShow}
onHide ={addModalClose}/>
</ButtonToolbar>
</div>
)
}
}
问题是您正在componentDidMount和componentDidUpdate中调用refreshList
。如文档中所述:https://reactjs.org/docs/react-component.html#componentdidupdate
您应该在某种情况下避免componentDidUpdate中的无限循环。
删除componentDidUpdate(),因为refreshData不依赖于道具来获取数据,并且不对prevProps和newProps进行任何检查。
您可以从添加或保存按钮回调中调用refreshData方法。
我认为您正在从模式代码中保存数据,请添加setState回调。
模式保存数据,隐藏设置显示状态为false并一次调用refreshData。
let addModalClose =()=> this.setState({addModalShow:false},this.refreshData)
您正在调用this.refreshList();
,它会执行某些操作,然后设置状态。设置状态后,将调用render
函数,然后再次调用componentDidUpdate
,从而设置无限循环。要使其工作,请与先前的props
比较,然后根据需要调用this.refreshList();
。
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.depid !== prevProps.depid) { //Replace `depid` with the props you like to compare changes. If that is changed, then only call
this.refreshList();
}
}
您可以立即在componentDidUpdate()中调用setState(),但请注意必须将其包装在上面示例中所示的条件下,或者您将导致无限循环。这也会造成额外的重新渲染虽然对用户不可见,但可能会影响组件性能。如果您尝试将某些状态“镜像”到道具来自上方,请考虑直接使用道具。读有关为何将道具复制到状态会导致错误的更多信息。
请参阅文档:https://reactjs.org/docs/react-component.html#componentdidupdate