You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目中redux-tooltip与react-simple-maps的Hook集成问题

解决redux-tooltip无法获取Redux状态的问题

看起来你遇到的核心问题是redux-tooltip的Tooltip组件无法正确读取Redux中的状态,同时没有触发tooltip的显示/隐藏动作。作为Redux新手,这几个基础点很容易踩坑,我来一步步帮你解决:

1. 修正Redux状态的读取路径

你当前的useSelector路径是错误的:

const tooltipState = useSelector(state => {
  return state.tooltip.default
});

redux-tooltip的reducer返回的状态是直接挂载在state.tooltip下的(因为你在combineReducers里把它命名为tooltip),并没有嵌套的default属性。正确的写法应该是:

const tooltipState = useSelector(state => state.tooltip);

不过其实你不需要手动读取这个状态传给Tooltip——因为redux-tooltip提供的<Tooltip />组件已经通过connect高阶组件自动连接到Redux了,只要你的store结构正确,它会自己读取状态。

2. 给地图元素添加tooltip触发事件

你现在的Geography组件没有绑定鼠标事件,所以Redux里的tooltip状态永远不会被更新,Tooltip自然无法显示。你需要在<Geography>上添加onMouseEnter和onMouseLeave来触发show和hide动作:

<Geography 
  key={i} 
  geography={geography} 
  projection={projection}
  // 添加鼠标事件
  onMouseEnter={(event) => {
    const countryCode = geography.properties["Alpha-2"];
    const countryName = geography.properties["NAME"];
    const value = dict[countryCode] || 0;
    
    // 触发tooltip显示动作,传入内容和位置
    dispatch(show({
      content: (
        <div className="tooltip-content">
          <h3>{countryName}</h3>
          <p>数值: {value}</p>
        </div>
      ),
      position: { 
        x: event.clientX + 10, // 偏移一点避免遮挡鼠标
        y: event.clientY + 10 
      }
    }));
  }}
  onMouseLeave={() => {
    // 触发tooltip隐藏动作
    dispatch(hide());
  }}
  // ... 你的style属性不变
/>

这样当鼠标 hover 到地理区域时,Redux中的tooltip状态会被更新,Tooltip组件就能感知到并显示内容了。

3. 关于next-redux-wrapper的误解

你提到示例用了next-redux-wrapper,但这个HOC是Next.js专属的Redux集成方案,用于在服务端渲染场景下同步store状态。你现在用的是普通React应用(通过ReactDOM.render和BrowserRouter),完全不需要这个工具——你当前的store配置(用Provider包裹App)是正确的,不用纠结这个点。

4. 验证Tooltip组件的正确性

确保你导入的Tooltip是redux-tooltip提供的已连接组件,它会自动从Redux读取show、content、position等状态,不需要你手动传props:

import { Tooltip, actions } from "redux-tooltip";

你当前的<Tooltip />写法是对的,只要Redux状态被正确更新,它就会正常显示。

完整修改后的地图组件片段

import { useSelector, useDispatch } from "react-redux";
import { ComposableMap, ZoomableGroup, Geographies, Geography, Markers, Marker } from "react-simple-maps";
import { scaleLinear } from "d3-scale";
import { Tooltip, actions } from "redux-tooltip";

const Detail = props => {
  const exposureScale = scaleLinear()
    .domain([0, props.val])
    .range(["white", "#f39c12"]);
  const dispatch = useDispatch();
  const { show, hide } = actions;
  // 如果你不需要手动使用tooltip状态,可以去掉这行
  // const tooltipState = useSelector(state => state.tooltip);

  return (
    <div>
      <ComposableMap>
        <ZoomableGroup disablePanning={true}>
          <Geographies geography={json} disableOptimization={false}>
            {(geographies, projection) => geographies.map((geography, i) => {
              const countryCode = geography.properties["Alpha-2"];
              // 初始化dict值
              if (!dict[countryCode]) dict[countryCode] = 0;

              return (
                <Geography 
                  key={i} 
                  geography={geography} 
                  projection={projection}
                  onMouseEnter={(event) => {
                    const countryName = geography.properties["NAME"];
                    const value = dict[countryCode];
                    dispatch(show({
                      content: (
                        <div>
                          <h4>{countryName}</h4>
                          <p>数值: {value}</p>
                        </div>
                      ),
                      position: { x: event.clientX + 10, y: event.clientY + 10 }
                    }));
                  }}
                  onMouseLeave={() => dispatch(hide())}
                  style={{
                    default: {
                      fill: exposureScale(dict[countryCode]),
                      stroke: "#607D8B",
                      strokeWidth: 0.75,
                      outline: "none"
                    },
                    hover: {
                      fill: "#607D8B",
                      stroke: "#607D8B",
                      strokeWidth: 0.75,
                      outline: "none"
                    },
                    pressed: {
                      fill: "#FF5722",
                      stroke: "#607D8B",
                      strokeWidth: 0.75,
                      outline: "none"
                    }
                  }}
                />
              );
            })}
          </Geographies>
        </ZoomableGroup>
      </ComposableMap>
      <Tooltip />
    </div>
  );
};

export default Detail;

最后检查点

  • 确认你的dict变量是可正确访问的(比如在组件内初始化或者作为props传入)
  • 打开Redux DevTools,查看当鼠标hover时,tooltip状态是否有变化(show变为true,content有值)
  • 如果还是报错,可以检查redux-tooltip的版本,确保和你的Redux版本兼容(比如Redux 4.x以上)

内容的提问来源于stack exchange,提问作者Raph117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:03:05