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

React中点击组件创建同类型组件的实现——点击多边形生成子多边形

嘿,我来帮你搞定这个地图多边形的实现问题~结合你给出的代码,我们可以分两步解决「地图加载完成生成初始多边形」和「点击多边形创建子多边形」的需求,具体方案如下:

实现思路与代码调整方案

1. 地图加载完成后初始化初始多边形

首先,地图组件一般都会提供初始化完成的回调事件(比如百度地图的onLoad、高德地图的onReady),我们需要在这个回调里请求初始区域数据(比如省级区域),然后更新state来渲染第一批多边形:

constructor(props) {
  super(props);
  this.state = {
    areas: [],
    currentAreaType: 'province' // 记录当前显示的区域层级,初始为省级
  };
}

// 地图初始化完成的回调方法
handleMapReady = () => {
  // 请求初始省级区域数据
  axios.get('http://127.0.0.1:8000/service/province/')
    .then(res => {
      this.setState({ areas: res.data });
    })
    .catch(err => console.error('初始区域数据加载失败:', err));
};

然后在你的地图组件JSX里绑定这个回调:

// 这里以高德地图组件为例,不同地图SDK的回调名可能不同
<AMap onReady={this.handleMapReady} />

2. 调整点击逻辑,正确渲染子多边形

你现有的clickHandler已经能通过接口获取子区域坐标,但当前的渲染逻辑有两个小问题:一是数据来源不统一(用this.props.areas渲染,但数据存在this.state.areas),二是点击后直接替换全部区域,没法实现层级切换或叠加子多边形。我给你两种常见场景的解决方案:

场景一:层级切换(点击省→显示市,点击市→显示区)

这种场景下,点击父多边形后会替换当前显示的区域,适合做行政区逐级下钻:

clickHandler = (id) => {
  // 根据当前层级推断下一级区域类型
  const nextAreaTypeMap = {
    province: 'city',
    city: 'district'
  };
  const nextAreaType = nextAreaTypeMap[this.state.currentAreaType];

  if (!nextAreaType) {
    console.log('已经到最小编辑层级啦~');
    return;
  }

  axios.get(`http://127.0.0.1:8000/service/${nextAreaType}/${id}/`)
    .then(res => {
      this.setState({ 
        areas: res.data,
        currentAreaType: nextAreaType // 更新当前层级
      });
    })
    .catch(err => console.error('子区域数据加载失败:', err));
};

// 可选:添加返回上一级的方法
backToPrevLevel = () => {
  const prevAreaTypeMap = {
    city: 'province',
    district: 'city'
  };
  const prevAreaType = prevAreaTypeMap[this.state.currentAreaType];
  
  // 这里需要根据业务逻辑获取上一级区域的ID,比如可以维护一个层级历史栈
  // 示例中假设你有记录上一级的ID为prevAreaId
  axios.get(`http://127.0.0.1:8000/service/${prevAreaType}/${this.state.prevAreaId}/`)
    .then(res => {
      this.setState({ 
        areas: res.data,
        currentAreaType: prevAreaType
      });
    });
};

render() {
  return (
    <>
      {/* 显示返回按钮(如果需要) */}
      {this.state.currentAreaType !== 'province' && (
        <button onClick={this.backToPrevLevel}>返回上一级</button>
      )}
      {/* 渲染当前层级的多边形 */}
      {this.state.areas.map(area => (
        <Polygon
          id={area.name}
          key={area.id}
          paths={area.coordinates}
          name={area.name}
          strokeColor={'#000000'}
          strokeOpacity={1}
          strokeWeight={1.2}
          fillOpacity={0.3}
          fillColor={'#00ff00'}
          onClick={() => this.clickHandler(area.id)}
        />
      ))}
    </>
  );
}

场景二:叠加子多边形(保留父多边形,新增子多边形)

如果需要点击父多边形后,在地图上同时显示父、子多边形(比如在省范围内显示所有市),可以调整state为累加式的数组:

clickHandler = (id, areaType) => {
  // 这里可以根据当前区域类型推断子区域类型,示例中直接用'city'
  const nextAreaType = 'city';
  axios.get(`http://127.0.0.1:8000/service/${nextAreaType}/${id}/`)
    .then(res => {
      // 将子区域数据追加到现有数组中
      this.setState(prevState => ({
        areas: [...prevState.areas, ...res.data]
      }));
    })
    .catch(err => console.error('子区域数据加载失败:', err));
};

render() {
  return (
    this.state.areas.map(area => (
      <Polygon
        id={area.name}
        key={area.id}
        paths={area.coordinates}
        name={area.name}
        strokeColor={'#000000'}
        strokeOpacity={1}
        strokeWeight={1.2}
        fillOpacity={0.3}
        fillColor={'#00ff00'}
        onClick={() => this.clickHandler(area.id, area.type)} // 假设area包含type字段标识层级
      />
    ))
  );
}

几个关键注意点

  • 确保你的Polygon组件能正确解析paths坐标,不同地图SDK的经纬度顺序可能不同(比如有些是[经度, 纬度],有些是[纬度, 经度]),如果渲染异常优先检查坐标格式
  • 一定要给接口请求加上catch逻辑,避免请求失败导致页面崩溃
  • 如果是层级切换场景,建议维护一个层级历史栈,方便记录每一步的区域ID和类型,这样返回上一级会更灵活

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:12:52