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

React Image Mapper点击两次才更新标记位置问题求助

解决react-image-mapper点击两次才更新标记位置的问题

我之前也碰到过类似的状态更新闭包坑,你的问题根源在于状态更新时没用到函数式更新,加上闭包导致的旧状态引用。

问题分析

你的updateMapArea函数直接依赖了当前的mapAreas状态,但React的状态更新是异步的,而且handleUpdateMapArea用useCallback包裹时没设置正确的依赖,导致第一次点击时,函数里拿到的还是初始的mapAreas快照。更新后的状态没能及时反映到下一次的状态计算里,这就造成第一次点击状态更新没生效,第二次点击才拿到正确状态完成更新。

修复方案

我们只需要做两处核心调整:

  1. 使用函数式状态更新修改mapAreas,确保每次更新都基于最新的状态值,而非闭包里的旧值。
  2. 简化回调逻辑,避免不必要的函数依赖陷阱。

修改后的完整代码如下:

import React, { useState, useCallback } from "react";
import ImageMapper from "react-image-mapper";
import "./styles.css";

export default function App() {
  const [mapAreas, setMapAreas] = useState({
    name: "my-map",
    areas: [
      { id: 5, shape: "circle", coords: [170, 100, 10], preFillColor: "#fff" }
    ]
  });

  const getTipPosition = area => {
    const obj = { top: `${area.center[1]}px`, left: `${area.center[0]}px` };
    console.log(obj);
  };

  const handleUpdateMapArea = useCallback(
    (evt) => {
      // 用函数式更新,基于最新状态修改
      setMapAreas(prevMap => {
        const updatedAreas = prevMap.areas.map(item => 
          item.id === 5 ? { ...item, coords: [evt.nativeEvent.layerX, evt.nativeEvent.layerY, 10] } : item
        );
        return { ...prevMap, areas: updatedAreas };
      });
    },
    [] // 无需依赖,因为函数式更新不依赖外部状态
  );

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <ImageMapper
        src="https://c1.staticflickr.com/5/4052/4503898393_303cfbc9fd_b.jpg"
        onClick={area => getTipPosition(area)}
        onImageClick={handleUpdateMapArea}
        map={mapAreas}
        width={500}
      />
      <pre>On each click, circle should be position of the clicked</pre>
    </div>
  );
}

关键修改点解释

  • 函数式状态更新:setMapAreas(prevMap => {...}) 这种写法会让React传入当前最新的状态值prevMap,我们基于这个最新值修改areas数组,彻底避免了闭包带来的旧状态问题。
  • 简化回调逻辑:把原来的updateMapArea逻辑直接整合到handleUpdateMapArea里,不需要额外的函数依赖,useCallback的依赖数组可以保持为空,代码更简洁可靠。

修改后,每次点击图片,圆形标记都会立即移动到点击位置,不会再出现需要点击两次的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:07:37