创建、编辑或删除新行后表格不更新
Posted
技术标签:
【中文标题】创建、编辑或删除新行后表格不更新【英文标题】:Table doesn't update after create, edit or delete new row 【发布时间】:2020-09-25 02:59:29 【问题描述】:我正在使用带有 Material-UI 的 ReactJs 来显示 Car 组件表,但在创建、编辑或删除一行后从不更新。 接下来是结构:
class MainCar extends React.Component
constructor(props)
super(props);
this.state =
cars: []
;
this.apiUrl = "http://localhost:8080/api/v1/cars";
this.onCreate = this.onCreate.bind(this);
this.onUpdate = this.onUpdate.bind(this);
this.onDelete = this.onDelete.bind(this);
this.loadFromServer = this.loadFromServer.bind(this);
loadFromServer()
fetch(this.apiUrl)
.then(response => response.json())
.then(json =>
this.setState(
cars: json.cars
);
);
onCreate(newCar)
try
const result =
fetch(this.apiUrl,
method: 'POST',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
body: JSON.stringify(newCar)
);
catch(e)
console.error(e);
this.loadFromServer();
onUpdate(car, updatedCar)
try
const result =
fetch(car._links.self.href,
method: 'PUT',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
body: JSON.stringify(updatedCar)
);
catch(e)
console.error(e);
this.loadFromServer();
onDelete(car)
try
const result =
fetch(car._links.self.href,
method: 'DELETE',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
body: JSON.stringify(car)
);
catch(e)
console.error(e);
this.loadFromServer();
render()
return (
<CarsTable cars=this.state.cars
onCreate=this.onCreate
onUpdate=this.onUpdate
onDelete=this.onDelete />
);
class CarsTable extends React.Component
constructor(props)
super(props);
render()
const cars = this.props.cars.map(car =>
<Car key=car._links.self.href
car=car
onUpdate=this.props.onUpdate
onDelete=this.props.onDelete />
);
return (
<Table>
<TableBody>
cars
</TableBody>
</Table>
);
class Car extends React.Component
constructor(props)
super(props);
render()
return (
<TableRow>
<TableCell>car.code</TableCell>
<TableCell>car.color</TableCell>
</TableRow>
);
如您所见,MainCar 的状态有 cars 数组,但 CarTable 和 Car 只有属性。
当我登录渲染函数时,我看到数据已更改,但视图未更新。
仅查看更新
当我按 F5 更新页面时。 或者,当我创建、更新或删除新行时,我看到了之前的更改,但没有看到最后的更改。我读到 React 在状态改变时会重新渲染组件。我应该为从道具复制的 CarTable 和 Car 组件设置状态吗?我该如何解决这个问题?
提前致谢。
【问题讨论】:
您确定onCreate
、onUpdate
和onDelete
的额外详细信息不相关吗?也许您没有在重新加载服务器数据之前等待这些操作完成,因此您正在获取修改前的数据。
@Jacob 代码已更新
【参考方案1】:
可能发生的情况是您的 GET 请求在您的 POST/PUT/DELETE 完成之前返回。解决此问题的一种方法是通过将 GET 放入 then
块中,确保仅在其他操作完成后触发 GET。
例如
onDelete(car)
try
const result =
fetch(car._links.self.href,
method: 'DELETE',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
body: JSON.stringify(car)
).then(a => this.loadFromServer());
catch(e)
console.error(e);
【讨论】:
【参考方案2】:你需要在 javascript 中等待异步的东西。否则,您将并行执行POST
和GET
,而不是按顺序执行。您可以使用async
函数来简化此操作。
async onCreate(newCar)
try
await fetch(this.apiUrl,
method: 'POST',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
body: JSON.stringify(newCar)
);
catch(e)
console.error(e);
return this.loadFromServer();
【讨论】:
我浪费时间寻找这个解决方案。你能推荐一个网站来学习这些关于 Javascript 的概念吗?我正在从 C++ 世界来到 Javascript 世界。 最重要的是要了解 JavaScript 的执行模型(事件循环)。有很多关于它的好文章;这是一个:developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop【参考方案3】:您的代码看起来应该可以工作(我知道这不是最有帮助的事情,但如果它显然不起作用),但这里有一些您可以尝试的事情。尝试在构造函数中的函数上执行bind(this)
,并尝试调用 this.loadFromServer(),而不是 loadFromServer()。另外,我猜你只是把这个从你的帖子中删除了,但你错过了 onDelete
见下文(查看构造函数和 onCreate 方法):
class MainCar extends React.Component
constructor(props)
super(props);
this.loadFromServer = this.loadFromServer.bind(this);
this.onCreate = this.onCreate.bind(this);
this.onUpdate = this.onUpdate.bind(this);
this.state =
cars: []
;
loadFromServer()
fetch(this.apiUrl)
.then(response => response.json())
.then(json =>
this.setState(
cars: json.cars
);
);
onCreate()
// more code to create...
this.loadFromServer(); // to update cars state
onUpdate()
// more code to put...
this.loadFromServer(); // to update cars state
render()
return (
<CarsTable cars=this.state.cars
onCreate=this.onCreate
onUpdate=this.onUpdate
onDelete=this.onDelete />
);
【讨论】:
道歉。你所有的建议都是关于实际代码的。以上是关于创建、编辑或删除新行后表格不更新的主要内容,如果未能解决你的问题,请参考以下文章
Eloquent - 编辑表格行并返回新结果数据 - 检索旧数据
如何用Java实现目录树的创建,结点编辑(创建,更新,删除等功能) 用ssh 需要前台js代码