反应 - 单击按钮后状态设置为空

时间:2021-06-28 23:00:09

标签: reactjs typescript

我有我的代码:

function App() {
  const [refundData, setRefundData] = useState(Array<ICancellationRefundOptionModel>());
  const [grid, setGridData] = useState(Array<JSX.Element>());

  useEffect(() => {
    getFailedRequests()
  }, []);

  const getFailedRequests = async () => {
    const failedRefundData = await getRequestAsync("myApiUrl")
    setRefundData(failedRefundData);
    createTable(failedRefundData);
  }

  const createTable = (dataArray: Array<ICancellationRefundOptionModel>) => {
    const dataTable = dataArray.map(x => {
      return (<tr>
        <td>{x.customerId}</td>        
        <td><button onClick={() => handleOnClick(x)}>Process</button></td>
      </tr>
      )
    })
    setGridData(dataTable);
  }

  const handleOnClick = async (refund: ICancellationRefundOptionModel) => {
    await postRequestAsync(refund, "");
    const newGrid = refundData.filter((item) => item.customerId !== refund.customerId);

    createTable(newGrid);
  }

  return (
    <div className="App">
      <Table striped bordered hover>
        <thead>
          <tr>
            <th>Customer Id</th>            
            <th></th>
          </tr>
        </thead>
        <tbody>
          {grid}
        </tbody>
      </Table>
    </div>
  );
}

export default App;

这会调用我的 api,在那里我获取我的数据以填充表格。我想要做的是在用户单击 Process 按钮之一后,该客户被处理,因此该行将从我的表中删除,但问题是当我单击其中一个按钮时,“refundData”状态是空的,即使它在页面加载后有一个值(我在 getFailedRequests 方法中放置了一个 console.log 并且它拥有它应该拥有的所有数据)。

我不太明白为什么将refundData设置为空。

1 个答案:

答案 0 :(得分:1)

正如 Drew Reese 在评论中指出的那样 - 您不应该将网格存储为状态对象。相反,只需在返回 refundData 后即时渲染它。

如果您将组件简化如下,不仅更容易理解,而且应该可以解决您的闭包问题。请注意,handleOnClick 事件处理程序现在会在点击事件之后更改 refundData 状态 - 这样做的最终效果是它会导致表格在没有已删除行的情况下呈现。

function App() {
  const [refundData, setRefundData] = useState<ICancellationRefundOptionModel[]>([]);

  useEffect(() => {
    getFailedRequests();
  }, []);

  const getFailedRequests = async () => {
    const failedRefundData = await getRequestAsync("myApiUrl")
    setRefundData(failedRefundData);
  }

  const handleOnClick = async (refund: ICancellationRefundOptionModel) => {
    await postRequestAsync(refund, "");
    setRefundData(prev => prev.filter((item) => item.customerId !== refund.customerId));
  }

  return (
    <div className="App">
      <Table striped bordered hover>
        <thead>
          <tr>
            <th>Customer Id</th>            
            <th></th>
          </tr>
        </thead>
        <tbody>
          {refundData?.length && refundData.map(x => (
            <tr>
                <td>{x.customerId}</td>        
                <td><button onClick={() => handleOnClick(x)}>Process</button></td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  );
}

export default App;