我从套接字监听数据。当我收到数据时,我像这样更新数组。但是状态没有更新。请帮助我并提前致谢

发布于 2025-01-16 17:16:15 字数 623 浏览 0 评论 0原文

socket?.on('addLocation', data => {
  console.log('addLocation', data);
  let isFound = false;
  let newMarkers = markers.map(marker => {
    if (marker.fleet_id == data.fleetId) {
      isFound = false;
      return {
        ...marker,
        latitude: data.lat,
        longitude: data.long,
      };
    } else {
      return marker;
    }
  });

  if (!isFound) {
    newMarkers = [
      ...newMarkers,
      {
        fleet_id: data.fleetId,
        latitude: data.lat,
        longitude: data.long,
      },
    ];
  }
  setMarker(newMarkers);
})
socket?.on('addLocation', data => {
  console.log('addLocation', data);
  let isFound = false;
  let newMarkers = markers.map(marker => {
    if (marker.fleet_id == data.fleetId) {
      isFound = false;
      return {
        ...marker,
        latitude: data.lat,
        longitude: data.long,
      };
    } else {
      return marker;
    }
  });

  if (!isFound) {
    newMarkers = [
      ...newMarkers,
      {
        fleet_id: data.fleetId,
        latitude: data.lat,
        longitude: data.long,
      },
    ];
  }
  setMarker(newMarkers);
})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦亿 2025-01-23 17:16:15

假设 markers 的状态是 setMarker 正在更新,那么这似乎是 markers 状态上的陈旧封装问题。回调正在更新关闭状态,而不是当前的标记状态值。

使用功能状态更新来正确访问以前的状态而不是过时的值。 Array.prototype.map 旨在将一组值映射到另一组值,并且不应该产生像设置 isFound 标志这样的副作用。首先搜索数据以确定是否需要更新状态或是否需要附加新元素。

例子:

socket?.on('addLocation', data => {
  console.log('addLocation', data);
  setMarker(markers => {
    const isFound = markers.some(marker => marker.fleet_id == data.fleetId);

    if (isFound) {
      return markers.map(marker => marker.fleet_id == data.fleetId
        ? {
          ...marker,
          latitude: data.lat,
          longitude: data.long,
        }
        : marker
      );
    }

    return [
      ...markers,
      {
        fleet_id: data.fleetId,
        latitude: data.lat,
        longitude: data.long,
      },
    ];
  });
});

Assuming markers the state that setMarker is updating then this appears to be an issue of a stale enclosure over the markers state. The callback is updating the closed over state and not the current markers state value.

Use a functional state update to correctly access the previous state instead of the stale value. Array.prototype.map is meant to map one set of values to another, and shouldn't have side-effects like setting an isFound flag. Search the data first to decide if the state needs to be updated or if a new element needs to be appended.

Example:

socket?.on('addLocation', data => {
  console.log('addLocation', data);
  setMarker(markers => {
    const isFound = markers.some(marker => marker.fleet_id == data.fleetId);

    if (isFound) {
      return markers.map(marker => marker.fleet_id == data.fleetId
        ? {
          ...marker,
          latitude: data.lat,
          longitude: data.long,
        }
        : marker
      );
    }

    return [
      ...markers,
      {
        fleet_id: data.fleetId,
        latitude: data.lat,
        longitude: data.long,
      },
    ];
  });
});
錯遇了你 2025-01-23 17:16:15
socket?.on('addLocation', ({ fleetId, lat, long }) => {
  setMarkers(existing => {
    const latLng = { latitude: lat, longitude: long };
    const index = existing.findIndex(m => m.fleet_id === fleetId);
    if (index === -1) {
      return [...existing, {
        fleet_id: fleetId,
        ...latLng
      }]
    } else {
      const clone = [...existing];
      clone[index] = {
        ...clone[index],
        ...latLng
      }
      return clone;
    }
  });
});

这里有一些事情:

  1. 您应该使用 setMarkers 的回调风格来确保您在修改时拥有“最新”副本。
  2. 写的代码相当复杂,你可以简化很多。 isFound 永远是 false 也是一个逻辑问题。
socket?.on('addLocation', ({ fleetId, lat, long }) => {
  setMarkers(existing => {
    const latLng = { latitude: lat, longitude: long };
    const index = existing.findIndex(m => m.fleet_id === fleetId);
    if (index === -1) {
      return [...existing, {
        fleet_id: fleetId,
        ...latLng
      }]
    } else {
      const clone = [...existing];
      clone[index] = {
        ...clone[index],
        ...latLng
      }
      return clone;
    }
  });
});

There are a few things here:

  1. You should use the callback flavour of setMarkers to ensure you have the "latest" copy when you're modifying it.
  2. The code as written is pretty convoluted, you can simplify it a lot. isFound will always be false is also a logic issue.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文