Open cuttlas opened 5 years ago
The same problem. Anybody?
Is your source being set using a spread operator or are you using any spread operators in your mapbox react code in general? If so, that is what will cause the flicker because this wrapper will think something drastic changed whenever it sees that a new object was passed to it. See if that fixes the issue.
@cuttlas a quick fix could be to create a component with 'Layer' and 'Popup' childs (above 'Layers' component, waiting until your source is loaded), and in same level, adding the 'Source' component. An example of a possible solution could be:
· Main component
import React from 'react';
import ReactMapboxGL, { MapContext, Source, ZoomControl } from 'react-mapbox-gl';
import Layers from '../../layers/Layers';
const Map = ReactMapboxGL({
accessToken:
'pk.eyJ1IjoiZG90Z2lzIiwiYSI6ImNqd3Z6amtjMTBjOTA0OW84ZjVvYzF6bjQifQ.LIbUaYq3GaiWTzsBV6YnTA'
});
const style = 'mapbox://styles/mapbox/dark-v10';
const LAYERS_CONFIG = {
cadastre_id: {
id: 'public.test',
sourceId: 'cadastre_source_id',
sourceLayer: 'public.test'
}
};
const Main = () => {
const [sourcesLoaded, setLoaded] = React.useState({
testLayer: false
});
const [allLoaded, setAllLoaded] = React.useState(null);
React.useEffect(() => {
if (sourcesLoaded) {
const all = Object.keys(sourcesLoaded).every(k => sourcesLoaded[k] === true);
all && setAllLoaded(true);
}
}, [sourcesLoaded]);
const manageLayersLoaded = layer => {
setLoaded({ ...sourcesLoaded, [layer]: true });
};
return (
<>
<Map
style={(styleHack => styleHack)(style)}
center={[-3.70379, 40.416775]}
zoom={[5]}
dragRotate={false}
movingMethod="jumpTo"
containerStyle={{
position: 'absolute',
height: '100%',
width: '100%',
top: 0,
padding: 0,
margin: 0
}}
>
<MapContext.Consumer>
{map => (
<>
<ZoomControl key="zoom-control" position="top-left" />
<Source
id={LAYERS_CONFIG.cadastre_id.sourceId}
tileJsonSource={{
type: 'vector',
tiles: ['http://devsolargalp.dotgiscorp.com:3000/public.test/{z}/{x}/{y}.pbf'],
promoteId: 'postal_code'
}}
onSourceLoaded={() => manageLayersLoaded('testLayer')}
/>
{allLoaded && <Layers key="map" map={map} config={LAYERS_CONFIG} />}
</>
)
}
</MapContext.Consumer>
</Map>
</>
);
};
export default Main;
· Layers component (with Popup)
import React from 'react';
import PropTypes from 'prop-types';
import { Map } from 'mapbox-gl';
import { Layer, Popup } from 'react-mapbox-gl';
import useMapEvents from './useMapEvents';
import PAINT from './paints';
import PopupTemplate from '../components/UI/PopupTemplate';
const Layers = ({ map, config }) => {
const [popupConfig] = useMapEvents(map, config);
return (
<>
<Layer
type="fill"
id={config.cadastre_id.id}
sourceId={config.cadastre_id.sourceId}
sourceLayer={config.cadastre_id.sourceLayer}
paint={PAINT.cadastrePaint}
/>
{popupConfig && popupConfig.coords && (
<Popup
coordinates={popupConfig.coords}
style={{ display: popupConfig.shouldRender ? '' : 'none' }}
>
<PopupTemplate label={popupConfig.staticLabel} content={popupConfig.info} />
</Popup>
)}
</>
);
};
Layers.propTypes = {
map: PropTypes.instanceOf(Map).isRequired,
config: PropTypes.object.isRequired
};
export default Layers;
I have a Layer of Markers that come from a tiles server:
When hovering one of the markers, I want to show a popup:
It works, but the layer markers hide for one second just after hovering. My guess is that showing/hidding the popup causes the Map to rerender, so the layer is rendered again, causing the flickering effect. Is there a way to prevent this behaviour??
Thanks.