问题描述
我正在尝试设置一个基于Redux状态飞往不同位置的MapBox。我正在使用两个useEffects:第一个用于渲染地图,第二个用于根据状态变化而飞到位置。我这样做是为了不使每个状态更改都重新渲染地图,这会阻止平滑的flyTo动画。我试图在useEffects之外声明一个全局映射变量,以使其具有全局范围,但是在状态更改时,第二个useEffect的映射变量未定义。
我在寻找一种无需重新渲染整个地图就可以更新地图位置的方法时遇到了麻烦。我以为第二个useEffect可以解决问题,但是这个全局声明的变量不起作用,我不确定为什么。
const Map = (props) => {
mapBoxgl.accesstoken = 'ACCESS_TOKEN';
const mapContainer = useRef(null);
let map;
useEffect(() => {
map = new mapBoxgl.Map({
container: mapContainer.current
});
},[]);
useEffect(() => {
map.flyTo({
center: [
props.map.lng,props.map.lat
]
})
map.zoom = props.map.zoom;
new mapBoxgl.Marker().setLngLat(props.map).addTo(map);
},[props.map]);
return (
<div>
<div ref={mapContainer} className={styles.mapContainer}/>
</div>
);
};
const mapStatetoProps = state => {
return {
map: state.map
}
}
export default connect(mapStatetoProps)(Map);
解决方法
map
在每个渲染周期都被重新声明,因此在未由第一个效果设置时未定义。也使用ref来存储map
。记住要通过map.current
访问以获得引用的当前值。
const Map = (props) => {
mapboxgl.accessToken = 'ACCESS_TOKEN';
const mapContainer = useRef(null);
const map = useRef();
useEffect(() => {
map.current = new mapboxgl.Map({
container: mapContainer.current
});
},[]);
useEffect(() => {
map.current.flyTo({
center: [
props.map.lng,props.map.lat
]
})
map.current.zoom = props.map.zoom;
new mapboxgl.Marker().setLngLat(props.map).addTo(map.current);
},[props.map]);
return (
<div>
<div ref={mapContainer} className={styles.mapContainer}/>
</div>
);
};