我有我的代码:
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设置为空。
答案 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;