创建、编辑或删除新行后表格不更新

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 组件设置状态吗?我该如何解决这个问题?

提前致谢。

【问题讨论】:

您确定onCreateonUpdateonDelete 的额外详细信息不相关吗?也许您没有在重新加载服务器数据之前等待这些操作完成,因此您正在获取修改前的数据。 @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 中等待异步的东西。否则,您将并行执行POSTGET,而不是按顺序执行。您可以使用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代码

SqlDataAdapter.Update(dataset) 方法插入新行但不更新现有行

Sql 触发器在表更新时添加新行

创建将更新属性的触发器

在Angular中取消或关闭模式后如何不更新数据?