我已经开始学习react hook,我想用从后端获得的cooridnate在初始渲染时加载地图,但不知何故,我的地图在我的api返回数据之前就已经渲染好了,我如何确保我的地图会一直等到数据返回?我需要对此提出任何条件吗?
下面是api代码
import React, { useState, useEffect, useRef } from "react";
import { useDispatch, useSelector } from 'react-redux';
import mapboxgl from 'mapbox-gl';
import { getBikeInfo, mapDetails } from './features/counter/getInfo/getDetails.js'
function App() {
const dispatch = useDispatch();
const dataToDisplay = useSelector(mapDetails);
const mapContainer = useRef(null);
mapboxgl.accessToken = 'pk.eyJ1IjoidmloYW5nMTYiLCJhIjoiY2ttOHowc2ZhMWN2OTJvcXJ0dGpiY21pNyJ9.hK5Wxwby89E7tKWoBoY5bg';
useEffect(() => {
dispatch(getBikeInfo())
var map = new mapboxgl.Map({
container: mapContainer.current,
style: 'mapbox://styles/mapbox/light-v10',
center: [-96, 37.8],
zoom: 3
});
console.log('mapdetails:' + mapDetails)
console.log('data display:' + dataToDisplay)
map.on('load', function () {
// Add an image to use as a custom marker
map.loadImage(
'https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png',
function (error, image) {
if (error) throw error;
map.addImage('custom-marker', image);
// Add a GeoJSON source with 2 points
map.addSource('points', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': dataToDisplay
}
});
// Add a symbol layer
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'points',
'layout': {
'icon-image': 'custom-marker',
// get the title name from the source's "title" property
'text-field': ['get', 'title'],
'text-font': [
'Open Sans Semibold',
'Arial Unicode MS Bold'
],
'text-offset': [0, 1.25],
'text-anchor': 'top'
}
});
}
);
});
}, []);
return (
<div className="district-map-wrapper">
<div id="districtDetailMap" className="map">
<div style={{ height: "100%" }} ref={mapContainer}>
</div>
</div>
</div>
);
}
export default App;
下面是我更新的代码:
useEffect(() => {
if (dataToDisplay.length != 0) {
loadtheMap
}
}, []);
但是在一些刷新之后,我看到数据没有被填充并且将CCD_ 1设置为CCD_。
更新1:根据建议,我已经像这个一样更新了我的代码
if(!dataLoaded) { // do not render anything if you're not ready
return (
<div className="hidden">
<div id="districtDetailMap" className="map">
<div style={{ height: "100%" }} ref={mapContainer}>
</div>
</div>
</div>);
}
其中className=";隐藏的">在App.css中定义,如下
.hidden{
display: none;
}
但我仍然在同一个问题上
根据请求PFB我的沙箱链接
codesandbox
由于您使用的是useEffect
,因此基本上可以保证您的组件在启动查询之前会渲染一次
如果您想确保您的组件不会被渲染,请使用一些标志来指示数据已准备好,在设置Map后将其设置为true
,并在该标志为false
时有条件地渲染一些回退ui
function App() {
const [dataLoaded, setDataLoaded] = useState(false); // introduce the flag
const dispatch = useDispatch();
const dataToDisplay = useSelector(mapDetails);
const mapContainer = useRef(null);
mapboxgl.accessToken = 'pk.eyJ1IjoidmloYW5nMTYiLCJhIjoiY2ttOHowc2ZhMWN2OTJvcXJ0dGpiY21pNyJ9.hK5Wxwby89E7tKWoBoY5bg';
useEffect(() => {
dispatch(getBikeInfo())
var map = new mapboxgl.Map({
container: mapContainer.current,
style: 'mapbox://styles/mapbox/light-v10',
center: [-96, 37.8],
zoom: 3
});
console.log('mapdetails:' + mapDetails)
console.log('data display:' + dataToDisplay)
map.on('load', function () {
// Add an image to use as a custom marker
map.loadImage(
'https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png',
function (error, image) {
if (error) throw error;
map.addImage('custom-marker', image);
// Add a GeoJSON source with 2 points
map.addSource('points', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': dataToDisplay
}
});
// Add a symbol layer
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'points',
'layout': {
'icon-image': 'custom-marker',
// get the title name from the source's "title" property
'text-field': ['get', 'title'],
'text-font': [
'Open Sans Semibold',
'Arial Unicode MS Bold'
],
'text-offset': [0, 1.25],
'text-anchor': 'top'
}
});
setDataLoaded(true); // set it to true when you're done
}
);
});
}, []);
return (
<div className="district-map-wrapper" style={dataLoaded ? undefined : {display: 'none'}}>
<div id="districtDetailMap" className="map">
<div style={{ height: "100%" }} ref={mapContainer}>
</div>
</div>
</div>
);
}