【问题标题】:setting state doesn't work properly when trying to set coordinates尝试设置坐标时设置状态无法正常工作
【发布时间】:2021-09-04 13:07:50
【问题描述】:
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 返回空数组,即使第一个 console.log 确实返回了所需的输出)。 但是当我第二次尝试时,即获取新的 coordList 值时,setCoords 设置了以前的 coordsList 的数据(第一个 console.log 正确返回 coordsList,但第二个 console.log 返回 coordsList 的先前数据)。

截图更清晰,

我第一次得到 coordsList,

第二次,

【问题讨论】:

    标签: reactjs react-leaflet react-leaflet-draw


    【解决方案1】:

    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);
    

    【讨论】:

      【解决方案2】:

      因为 state 只有在组件重新渲染时才有新值。所以你应该将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]);
      

      【讨论】:

        【解决方案3】:

        因为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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-13
          • 1970-01-01
          • 1970-01-01
          • 2021-01-16
          • 2013-02-08
          • 2014-09-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多