尝试设置坐标时设置状态无法正常工作

setting state doesn't work properly when trying to set coordinates

function MyMap({ floorsByBuilding }: MyMapProps) {
  const [coords, setCoords] = useState<any[]>([]);

  const created = (e) => {
    const coordsList = e.layer.editing.latlngs[0][0];
    console.log("coordsList:", coordsList);
    setCoords(coordsList);
    console.log("Coords:",coords);
  };

  return (
    <div className="mapview">
      <div className="myMap">
        <Map center={[0, 0]} zoom={1}>
          <FeatureGroup>
            <EditControl
              position="topright"
              draw={{
                rectangle: false,
                circle: false,
                circlemarker: false,
                polyline: false,
              }}
              onCreated={created}
            />
          </FeatureGroup>
        </Map>
      </div>
    </div>
  );
}

e.layer.editing.latlngs[0][0] 貌似,

[
   {
      "lat":32.29840589562344,
      "lng":80.85780182804785
   },
   {
      "lat":17.421213563227735,
      "lng":78.36653079164644
   },
   {
      "lat":23.02755815843566,
      "lng":107.33497479055386
   },
   {
      "lat":41.49329414356384,
      "lng":104.47883340910323
   },
   {
      "lat":39.47390998063457,
      "lng":82.8312041405605
   }
]

EditControl 是 react-leaflet-draw 组件,有助于在图像或地图中进行注释,我们从中获取坐标(上述数据)e.layer.editing.latlngs[0][0]。 获得坐标后,我试图将这些坐标存储到一个状态(即 setCoords)中,以便我可以在其他地方使用这些坐标。

这里的问题是, 在第一次获得 coordsList 之后,setCoords 实际上并没有设置那些坐标(第二个 console.log return 的空数组,即使第一个 console.log 确实 return所需的输出)。 但是当我第二次尝试时,即获得了一个新的 coordList 值,setCoords 设置了先前 coordsList 的数据(第一个 console.log return coordsList 正确但第二个 console.log return coordsList 之前的数据).

截图更清晰,

第一次得到coordsList,

第二次,

console.log 保留在 created() 函数之外。 setCoords() 是一个异步函数,因此状态不会立即更新以显示在 console.log 中,正如您提供的那样。所以把它放在外面重新渲染时可以看到。

  const created = (e) => {
    const coordsList = e.layer.editing.latlngs[0][0];
    console.log("coordsList:", coordsList);
    setCoords(coordsList);
  };

   console.log("Coords:",coords);

因为状态只有在组件重新渲染时才有新的值。所以你应该将 console.log 移动到 useEffect 以在组件重新渲染时检查新值。

const created = (e) => {
  const coordsList = e.layer.editing.latlngs[0][0];
  console.log("coordsList:", coordsList);
  setCoords(coordsList);
};

useEffect(() => {
  console.log("Coords:", coords);
}, [coords]);

是因为Reactjs's update batching机制


在 onChange、onClick 等事件处理程序中更新状态时,React 会将所有 setState 批处理为一个:

const created = (e) => {
  const coordsList = e.layer.editing.latlngs[0][0];
  console.log("coordsList:", coordsList);
  setCoords(coordsList);
  console.log("Coords:", coords);
};

将您的日志放在 return 函数之前以查看最新值:

function MyMap({ floorsByBuilding }: MyMapProps) {
  const [coords, setCoords] = useState<any[]>([]);

  const created = (e) => {
    const coordsList = e.layer.editing.latlngs[0][0];
    setCoords(coordsList);
  };

  console.log("Coords:",coords);
  return (
  ...
  )
}

但是如前所述,这种行为将在 Reactjs 18 中改变 here