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

问题描述 投票:0回答:1

我正在使用react-leaflet版本4.x。

我试图通过单击按钮来更新地图的缩放级别,就像一个简单的用例一样。我意识到您可以为

<MapContainer>
创建一个子组件并使用
useMap()
,但我希望能够使用位于
<MapContainer>
组件外部的控件来更改地图。因此,我正在使用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
。但我需要更新地图参考。我尝试放入
useEffect
来更新地图,但收到一条错误消息,表明
mapRef
无法正常工作:

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

无法读取 null 的属性(读取“setZoom”) 类型错误:无法读取 null 的属性(读取“setZoom”)

我还尝试将参考更改为

whenReady
并使用
useState
来保存地图参考:

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>

这给了我这样的错误:

map.setZoom 不是函数

我该怎么做?

编辑:我必须缺少从传单的导入才能访问

setZoom
功能,对吗?我如何获得这些方法?

reactjs redux react-redux leaflet react-leaflet
1个回答
0
投票

原来我需要做的就是将

ref
设置为
<MapContainer>
并将其与
useState
而不是
useRef
一起使用。我在react-leaflet文档中找到了使用外部控件控制地图的示例。

我最终的

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>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.