跳到主要内容

tlbs-map-react 通过 ref 设置中心点

· 阅读需 4 分钟
Quany
软件工程师

tlbs-map-react 中,通过 ref 设置地图中心点是一种非常灵活和强大的方式。下面我为您详细介绍几种实现方法:

🔧 方法一:使用 useRef 获取地图实例(推荐)

这是最常用和推荐的方法,通过 React 的 useRef Hook 获取地图实例,然后调用地图的原生方法。

import React, { useRef, useState } from 'react';
import { TMap } from 'tlbs-map-react';

const MapComponent = () => {
// 创建 ref 引用
const mapRef = useRef(null);
const [newCenter, setNewCenter] = useState({ lat: 39.916, lng: 116.397 });

// 地图加载完成后的回调
const handleMapLoad = (mapInstance) => {
mapRef.current = mapInstance;
console.log('地图实例已获取:', mapInstance);
};

// 通过 ref 设置中心点的函数
const setMapCenter = (lat, lng) => {
if (mapRef.current) {
// 方法1: 使用 setCenter 方法
mapRef.current.setCenter(new TMap.LatLng(lat, lng));

// 方法2: 或者使用 panTo 方法(平滑移动)
// mapRef.current.panTo(new TMap.LatLng(lat, lng));

console.log(`地图中心已设置为: ${lat}, ${lng}`);
} else {
console.warn('地图实例尚未就绪');
}
};

// 处理输入框变化
const handleInputChange = (e) => {
const { name, value } = e.target;
setNewCenter(prev => ({
...prev,
[name]: parseFloat(value)
}));
};

return (
<div style={{ width: '100%', height: '500px' }}>
{/* 控制面板 */}
<div style={{ marginBottom: '10px', padding: '10px', background: '#f5f5f5' }}>
<label>纬度: </label>
<input
type="number"
name="lat"
value={newCenter.lat}
onChange={handleInputChange}
step="0.0001"
/>
<label style={{ marginLeft: '10px' }}>经度: </label>
<input
type="number"
name="lng"
value={newCenter.lng}
onChange={handleInputChange}
step="0.0001"
/>
<button
onClick={() => setMapCenter(newCenter.lat, newCenter.lng)}
style={{ marginLeft: '10px' }}
>
设置中心点
</button>
</div>

{/* 地图组件 */}
<TMap
ref={mapRef}
apiKey="您的腾讯地图密钥"
options={{
center: newCenter, // 初始中心点
zoom: 12
}}
onLoad={handleMapLoad}
/>
</div>
);
};

export default MapComponent;

🎯 方法二:创建自定义 Hook

为了更好的代码复用,可以创建一个自定义 Hook:

import { useRef, useCallback } from 'react';

// 自定义 Hook:用于地图操作
export const useMapControl = () => {
const mapRef = useRef(null);

const setCenter = useCallback((lat, lng) => {
if (mapRef.current) {
mapRef.current.setCenter(new TMap.LatLng(lat, lng));
return true;
}
return false;
}, []);

const getCenter = useCallback(() => {
if (mapRef.current) {
return mapRef.current.getCenter();
}
return null;
}, []);

const setZoom = useCallback((zoomLevel) => {
if (mapRef.current) {
mapRef.current.setZoom(zoomLevel);
}
}, []);

return {
mapRef,
setCenter,
getCenter,
setZoom
};
};

// 在组件中使用
const MyMap = () => {
const { mapRef, setCenter, getCenter } = useMapControl();

const handleSetToBeijing = () => {
setCenter(39.9042, 116.4074);
};

const handleLogCenter = () => {
const center = getCenter();
if (center) {
console.log('当前中心点:', center.lat, center.lng);
}
};

return (
<div>
<div>
<button onClick={handleSetToBeijing}>定位到北京</button>
<button onClick={handleLogCenter}>打印中心点</button>
</div>

<TMap
ref={mapRef}
apiKey="您的密钥"
options={{
center: { lat: 39.916, lng: 116.397 },
zoom: 10
}}
/>
</div>
);
};

📍 方法三:结合地理编码设置中心点

在实际应用中,经常需要根据地址名称来设置中心点:

import React, { useRef, useState } from 'react';
import { TMap } from 'tlbs-map-react';

const GeocodingMap = () => {
const mapRef = useRef(null);
const [address, setAddress] = useState('');

// 地理编码函数
const geocodeAddress = async (address) => {
try {
// 使用腾讯地图地理编码服务
const geocoder = new TMap.service.Geocoder();

return new Promise((resolve, reject) => {
geocoder.getLocation({ address: address }, (result) => {
if (result && result.result && result.result.location) {
resolve(result.result.location);
} else {
reject('地址解析失败');
}
});
});
} catch (error) {
console.error('地理编码错误:', error);
throw error;
}
};

const handleSearch = async () => {
if (!address.trim()) return;

try {
const location = await geocodeAddress(address);
if (mapRef.current && location) {
mapRef.current.setCenter(new TMap.LatLng(location.lat, location.lng));
mapRef.current.setZoom(15); // 放大到更详细的级别
}
} catch (error) {
alert('无法找到该地址,请重试');
}
};

return (
<div>
<div style={{ marginBottom: '10px' }}>
<input
type="text"
value={address}
onChange={(e) => setAddress(e.target.value)}
placeholder="输入地址..."
style={{ width: '300px', padding: '8px' }}
onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
/>
<button onClick={handleSearch} style={{ padding: '8px 16px', marginLeft: '10px' }}>
搜索
</button>
</div>

<TMap
ref={mapRef}
apiKey="您的密钥"
options={{
center: { lat: 39.916, lng: 116.397 },
zoom: 10
}}
style={{ width: '100%', height: '400px' }}
/>
</div>
);
};

⚠️ 重要注意事项

  1. 确保地图已加载:在调用 mapRef.current 的方法之前,务必检查 mapRef.current 不为 null

  2. 错误处理

const safeSetCenter = (lat, lng) => {
if (!mapRef.current) {
console.error('地图实例未就绪');
return;
}

try {
mapRef.current.setCenter(new TMap.LatLng(lat, lng));
} catch (error) {
console.error('设置中心点失败:', error);
}
};
  1. 性能优化:频繁设置中心点可能会影响性能,可以考虑使用防抖:
import { debounce } from 'lodash';

const debouncedSetCenter = debounce((lat, lng) => {
if (mapRef.current) {
mapRef.current.setCenter(new TMap.LatLng(lat, lng));
}
}, 300);

通过 ref 设置中心点为您提供了最大的灵活性,特别是在需要动态响应各种用户交互或数据变化的场景中。

微信公众号

微信公众号