So I got this code running to render a leaflet ok, trying to replace the url whenever the colorMode changes is the challenge here.
useEffect is triggered ok displaying the correct variable but I can't update that TileLayer in any way.
export const Map = () => {
const { colorMode } = useColorMode();
let state = { center: { lat: 51.505, lng: -0.09 }, zoom: 13 };
const colorModeUrl = ['https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png']
useEffect(() => {
console.log(colorMode);
}, [colorMode]);
return (
<MapContainer
center={state.center}
zoom={state.zoom}
style={{ height: '100%' }}>
<TileLayer url={colorMode === 'light' ? colorModeUrl[0] : colorModeUrl[1]} />
</MapContainer>
)
}
Looking at the TileLayer documentation, the url
prop is not mutable. After the initial render the component will not update if the prop is changed:
However, you can add a ref
to the layer and update the url that way
export const Map = () => {
const ref = useRef(null);
const state = { center: { lat: 51.505, lng: -0.09 }, zoom: 13 };
const { colorMode } = useColorMode();
const light = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const dark =
"https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png";
};
useEffect(() => {
if (ref.current) {
ref.current.setUrl(colorMode === "light" ? light : dark);
}
}, [colorMode]);
return (
<div>
<MapContainer
center={state.center}
zoom={state.zoom}
style={{ height: "100%" }}
>
<TileLayer ref={ref} url={colorMode === "light" ? light : dark} />
</MapContainer>
</div>
);
};
https://codesandbox.io/s/react-leaflet-forked-1534x?file=/src/index.js:0-1158