在使用React-Redux时,如何更新React-Leaflet V4中的mapRef?

rqenqsqc  于 2023-08-05  发布在  React
关注(0)|答案(1)|浏览(126)

我使用的是react-leaflet版本4.x。

我尝试在点击按钮时更新Map的缩放级别,这只是一个简单的用例。我知道您可以创建<MapContainer>的子组件并使用useMap(),但我希望能够使用位于<MapContainer>组件外部的控件更改Map。因此,我使用react-redux来尝试管理状态。
我创建了一个切片,其中缩放级别作为初始状态的一部分:

import { createSlice } from "@reduxjs/toolkit";

export const mapViewSlice = createSlice({
  name: "mapView",
  initialState: {
    zoom: 5,
  },
  reducers: {
    changeZoom: (state, action) => {
      state.zoom = action.payload;
    },
  },
});

export const { changeZoom } = mapViewSlice.actions;
export default mapViewSlice.reducer;

字符串
然后,我创建了Map组件,在其中单击按钮时调度changeZoom操作:

import React, { useState, useEffect, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import { MapContainer, TileLayer } from "react-leaflet";
import { changeZoom } from "./mapViewSlice";
import "./Map.css";

export const Map = () => {
  const mapRef = useRef(null);
  const zoomLevel = useSelector((state) => state.mapView.zoom);
  const dispatch = useDispatch();

  return (
    <div id="map-container" className="flex-container-row">
      <MapContainer center={[37.0902, -95.7129]} zoom={zoomLevel} ref={mapRef}>
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
      </MapContainer>
      <button onClick={() => dispatch(changeZoom(2))}>Change Zoom</button>
    </div>
  );
};


如果我单击按钮和console.log(zoomLevel),我会看到它返回值2。但我需要更新Map参考。我试着放一个useEffect来更新Map,但我得到一个错误,表明mapRef不能正常工作:

useEffect(() => {
    mapRef.current.setZoom(zoomLevel);
  }, [zoomLevel]);


无法读取null的属性(正在阅读“setZoom”)TypeError:无法读取null的属性(阅读“setZoom”)
我还尝试将ref改为whenReady,并使用useState来保存map引用:

const [map, setMap] = useState(null)
//...

useEffect(() => {
    if (map) {
      console.log(map);
      map.setZoom(zoomLevel);
    }
  }, [zoomLevel]);

//...
      <MapContainer center={[37.0902, -95.7129]} zoom={zoomLevel} whenReady={setMap}>
        //...
      </MapContainer>


这给了我一个这样的错误:
setZoom不是函数
我该怎么做?
编辑:我必须从传单中缺少一个导入才能访问setZoom函数,对吗?我如何获得这些方法?

carvr3hs

carvr3hs1#

原来我需要做的就是在<MapContainer>中设置ref,并将其与useState一起使用,而不是useRef。我在react-leaflet文档中发现了controlling the map with an external control的示例。
我的最终Map组件代码:

import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { MapContainer, TileLayer } from "react-leaflet";
import { changeZoom } from "./mapViewSlice";
import "./Map.css";

export const Map = () => {
  const [map, setMap] = useState(null);
  const zoomLevel = useSelector((state) => state.mapView.zoom);
  const dispatch = useDispatch();

  useEffect(() => {
    if (map) {
      map.setZoom(zoomLevel);
    }
  }, [zoomLevel, map]);

  return (
    <div id="map-container" className="flex-container-row">
      <MapContainer center={[37.0902, -95.7129]} zoom={zoomLevel} ref={setMap}>
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
      </MapContainer>
      <button onClick={() => dispatch(changeZoom(2))}>Change Zoom</button>
    </div>
  );
};

字符串

相关问题