reactjs - 如何在 React 中异步更新同一数组中的多个对象?
问题描述
我有一个应用程序,其类定义如下:
class Point {
id: string;
position: Coordinate;
elevation?: number;
}
在我的应用程序中,我存储了一组点。
const [points, setPoints] = useState<Point[]>([]);
在下面的代码中,我有一个依赖于points
数组的 useEffect 钩子;任何时间points
变化,效果都会扫描具有undefined
高程的点并异步查询高程。当单个查询返回时,将调用回调handleUpdatePoint
以使用新的高程值更新该特定点。
// Any time the Points array changes, checks each Point for undefined elevation
// and queries for it
// ISSUE: If more than one elevation query has yet to resolve, there will be an unintended
// state if one query resolves while one or more queries are pending
useEffect(() => {
points.forEach((p) => {
if (p.elevation === undefined) {
ElevationQuery(p.position.lat, p.position.lng, (elevation) => {
handleUpdatePoint(p.id, { elevation: elevation });
});
}
});
}, [handleUpdateSteerpoint, points]);`
我面临的问题是,如果多个查询同时挂起,则状态points
会在多个结果返回时被覆盖,从而丢失我的某些查询的提升结果。我怎样才能解决这个问题?
编辑#1:handleUpdatePoint
添加以供参考
const handleUpdatePoint = useCallback(
(id: string, newPointData: Partial<Point>) => {
// shallow copy the points array
const pointsClone = [...points];
// the point we are updating
const targetPoint = getPointById(id);
// preserve all other points as they are, but update the target point
// with the new data
const updatedPoints: Point[] = pointsClone.map((p: Point) => {
if (p.id !== id) {
return p;
} else {
// if the target point has a position, change its elevation to undefined
if (newPointData.position) {
newPointData.elevation = undefined;
}
const updatedPoint: Point = update(targetPoint, { $merge: newPointData })!;
return updatedPoint;
}
});
setPoints(updatedPoints);
},
[getPointById, points]
);
解决方案
只需使用回调样式更新您的状态就可以解决问题:
setPoints((previousPoints) =>
previousPoints.map((p: Point) => {
if (p.id !== id) {
return p;
} else {
// if the target point has a position, change its elevation to undefined
if (newPointData.position) {
newPointData.elevation = undefined;
}
const updatedPoint: Point = update(targetPoint, {
$merge: newPointData,
})!;
return updatedPoint;
}
})
);
推荐阅读
- python - SQLAlchemy 加入关联表
- python - 添加 CSS 文件后出现黑屏
- php - PHP7.3:如何在不在子类中重新声明的情况下,继承具有最大可能范围的受保护静态属性?
- mysql - 根据项目从两个 sql 表中求和和差异 - laravel
- css - 在 Safari 中垂直拉伸的图像,父容器作为 display flex
- c++ - 我应该将结构用作 C++ 中的参数化构造函数吗?
- android - 如何为电子商务 Android 应用程序制作管理面板或管理应用程序
- php - 有很多列的 SQL 的另一种解决方案吗
- php - 在 NGINX 服务器上运行多个 CakePHP 项目
- excel - 为什么 Excel 2016 VBA 代码在使用几次后会崩溃?