WMSTileLayer is not updating after changing the layers parameter in react-leaflet - javascript

I am trying to update my WMS layer on react-leaflet v2.x.x. The WMSTileLayer works only with the first layer and when I change the layers parameter on it, it shows the previously added layer. I have written following code,
<MapContainer
whenCreated={(mapInstance) => {
mapRef.current = mapInstance;
}}
center={[38.861, 71.2761]}
zoom={5}
zoomControl={false}
style={{ width: "100%", height: "70vh" }}
>
<ZoomControl position="topright" />
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution="© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"
/>
<WMSTileLayer
layers={this.props.wmsLayer}
url={`${process.env.REACT_APP_GEOSERVER_URL}/wms`}
transparent={true}
format={"image/png"}
/>
</MapContainer>
So my question is, how to update the WMSTileLayer when my this.props.wmsLayer is updated?

You are using the MapContainer component, which makes me suspect you are actually using react-leaflet version 3. In react-leaflet version 3, many props are immutable, meaning once they are set, changing them from a react props perspective will do nothing. You would need to get a ref to the underlying L.TileLayer.WMS and call a method on it to change the layers. Unfortunately, the leaflet docs do not seem to show any methods to do that (i.e. like a setLayers function or something like that). You could call setUrl on the tilelayer, though I'm not sure that's what you want.
The easiest thing to do would be to add a key prop to your WMSTileLayer, and set it to some unique id that will force react to rerender when this.props.wmsLayer changes. I'm not sure what this.props.wmsLayer is, but if it has some unique url or id associated with it, set key={this.props.wmsLayer.id} or whatever you can, and react will force rerender that component. It's a bit overkill, but without some kind of setLayers function in the leaflet api, I'm not sure that there's a more proper way to do it.

Related

How to use d3 component in react without breaking its animation

I was trying out d3 sunburst component from here. I wanted to use it in react. To use it in react, we have to use another library called react-kapsule:
import SunburstChart from "sunburst-chart";
import fromKapsule from "react-kapsule";
const ReactSunburst = fromKapsule(SunburstChart, {
methodNames: ["onClick"]
});
<ReactSunburst
width={200}
height={200}
label="name"
size="size"
data={flare}
onClick={(entry) => {
console.log("Hello from inside onClick handler!!");
}}
/>
It renders as follows:
The problem is with specifying custom onClick handler. When I specify methodNames: ["onClick"], clicking on slice of sunburst chart zooms in that slice, but it does not log the message to the console. codesandbox link
If I remove onClick from methodNames, it logs the message to method names, but it does not zooms in the slice. codesandbox link
How I add working onClick handler while at the same time ensuring that the component's default behavior wont break?

OnClick for mapbox Layer

I am using react-map-gl to add a map to my React app. I want to add an onClick event to my Layer component, but it looks like react-map-gl does not support it. (docs here: https://visgl.github.io/react-map-gl/docs/api-reference/layer )
I've recently discovered that react-mapbox-gl does support onClick events for Layer components, but I am having trouble installing it through npm (tree dependency issues).
I was wondering if anyone here has managed to add the onClick event using react-map-gl? Any advice?
Example code below:
import React from "react";
import { Layer, LayerProps } from "react-map-gl";
export const MapLayer: React.FunctionComponent<LayerProps> = ({
id,
type,
paint,
source,
layout,
}) => {
return (
<Layer id={id} type={type} paint={paint} source={source} layout={layout} />
);
};
Thanks,
Robert
In fact, react-map-gl would definitely support onClick event.
However, the event is not designed to respond to each individual layer, instead it comes under the default Map component. You will need to specify the interactiveLayerIds property to make it work on specific layers.
Please refer to the section of onClick event from react-map-gl documentation.

Can I use custom styling for loading message on #react-google-maps/api

I'm using #react-google-maps/api for my app and it works well so far, however, while the map is loading there is a very ugly text that says 'Loading...' displayed instead of a map and I was wondering if I can replace it with a proper loader or at least style the text?
Screenshot
Pass a ReactNode into the loadingElement prop.
const Loading = <div /> // change to whatever
<LoadScript
googleMapsApiKey={googleMapsApiKey}
...
loadingElement={Loading}
>...</LoadScript>
Example

Conditionally rendering the same component does not trigger mounted() hook

I'm pretty new to Vue so please correct me if my thinking process is wrong. I'm trying to conditionally render a component like this:
<div>
<Map v-if="bool" mapSrc="src1.jpg" :idList="idList1" :data="dataVariable1"></Map>
<Map v-else mapSrc="src2.jpg" :idList="idList2" :data="dataVariable2"></Map>
</div>
My goal here is to render the same component with different props depending on the v-if state. So when bool is true it should render the first component, and when i toggle bool to be false, it should render the second option. The props seems to be changing correctly, but when i toggle the bool state it does not seem to run the mounted() hook again, which is an indication that component1 does not seem to dismount, it just switches out the props basically.
What I want is that when bool is false, it should render a fresh version of that whole component instance, and be isolated of what previously was going on in component 1.
How can I achieve this?
according to Linus Borg's answer here, You should add a unique key attribute to both of them.
You can a achieve this by using key attribute
Specify different key for the 2 Map components.
<Map v-if="bool" mapSrc="src1.jpg" :idList="idList1" :data="dataVariable1" key="map1"></Map>
<Map v-else mapSrc="src2.jpg" :idList="idList2" :data="dataVariable2" key="map2"></Map>

Modify NavigationBar on route change

I can't find any documentation for how this should be done with the <Navigator/> component... Basically, when one of my scenes loads, I want to be able to, say, pass a route.navBarColor to my navigator that will automatically change the background color of the bar.
I have tried pushing a route with {navBarColor: 'red'}, etc... to renderScene(), but this does not work because renderScene() doesn't seem to have a reference to this, and when I bind(this) it, the entire scene does not render, and throws a Stack Overflow error.
Basically, I want to do something like this:
navigator.push({name: 'TestScene', navBarColor: 'transparent'})
Which then goes to
renderScene(route, navigator) {
if(route.navBarColor) {
this.setState({navBarColor: navBarColor});
} ... etc.
}
Where this.state.navBarColor is used to set the backgroundColor prop of the navigationBar.
Is this possible with the Navigator component? I see that it appears to be with NavigatorIOS, so I don't understand why it wouldn't be here.
Thanks!
The Navigator component has no display of its own, it only manages the scene transitions and routing, so asking how to do this "with Navigator" is not right. This is contrasted with NavigatorIOS which dictates the display as well.
Your question mentions "NavigationBar", is that React Native Navbar?
If yes, somewhere in the renderScene() function there will be a reference to the component, you simply need to pass it the appropriate navBarColor prop.
<NavigationBar statusBar={{ tintColor: route.navBarColor }} />

Categories