On a React app that displays maps, I made a side-by-side comparator using the leaflet-side-by-side plugin (I followed the answer to this thread) that works fine on its own.
However, some of the maps aren't free and I want to restrict access to them (and prevent requests for these tiles). For now, I've made it so that the tiles won't display unless you enter the right password. So basically, I need to update the locked TileLayer after it has been rendered. When I use react-leaflet, I just use setUrl to update the TileLayer when the password matches :
const LockedLayer = ({ lockedUrl, attribution }) => {
const pwd = Config.PWD;
const [inputPwd, setInputPwd] = useState(null);
const tileLayerRef = useRef(null);
useEffect(() => {
if (pwd === inputPwd) {
tileLayerRef.current.setUrl(lockedUrl);
}
});
return <TileLayer attribution={attribution} url="" ref={tileLayerRef} />;
};
which works perfectly fine.
But for leaflet-side-by-side, I need to use native Leaflet, which doesn't behave the same. The same code applied to a TileLayer created by L.tileLayer has no effect, even though the URL is correctly updated, the map will not update its content despite the layer changing (because it is inside of a hook, I assume). Like I mentioned, I copy-pasted the code from a thread before adding my own layers, which looks like:
import "leaflet-side-by-side";
...
const Map = () => {
useEffect(() => {
const map = L.map("map").setView([51.505, -0.09], 13);
const osmLayer = L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", { attribution: 'OSM' }).addTo(map);
const lockedLayer = LeafletLockedLayer(
"PROTECTED_URL", { attribution: 'credits'}
).addTo(map);
L.control.sideBySide(lockedLayer, osmLayer).addTo(map);
}, []);
return <div id="map" />;
};
const LeafletLockedLayer = ({ lockedUrl, attribution }) => {
const pwd = Config.PWD;
const [inputPwd, setInputPwd] = useState(null);
const tileLayer = L.tileLayer("", { attribution: attribution });
useEffect(() => {
if (pwd === inputPwd) {
tileLayer.setUrl(lockedUrl);
}
});
return tileLayer;
};
So far I've unsuccessfully tried:
- using map.invalidateSize() to force an update
- using a component similar to LockedLayer, but with L.tileLayer instead of
- rendering the map with a setTimeout (kind of glad this isn't the solution)
- only adding the TileLayer to the map if it is unlocked (it never shows up)
What I'm looking for is either a way to update and redraw the layers in leaflet-side-by-side, another way to restrict access to some layers, or an alternative to the plugin that would allow me to use react-leaflet.
Thanks in advance for any idea!