Reputation: 96
I have a functional parent Map
component with a few states, one of which is layers
, the value of which is set initially from a config.
I then have a child LayerControl
component which takes the layers state of the map as its props. The LayerControl component makes some changes and passes them back to the Map with onLayerChange
which then subsequently calls the setState method of the layers (setLayers
).
From what I understand, this should trigger a re-render of my LayerControl component, but it doesn't. What have I done wrong?
export default function Map(){
const [viewport, setViewport] = useState(mapConfig.viewport);
const [style, setStyle] = useState(mapConfig.mapStyle);
const [layers, setLayers] = useState(mapConfig.layers);
function updateLayers(layers){
setLayers(layers); //why won't LayerControl re-render?
}
return(
<MapGL
zoom={[viewport.zoom]}
containerStyle={{
height: "100%",
width: "100%"
}}
style={style}>
<LayerControl
onLayerChange={layers => updateLayers(layers)}
layers={layers}
/>
<ZoomControl/>
<ScaleControl/>
</MapGL>
);
}
Upvotes: 1
Views: 5634
Reputation: 4291
Are you creating a new layers Array in the LayerController or are you just adding/removing an item to the layers array? I assume setLayers
only does a shallow reference check to see if layers
changed, which will return false if you modified the array instead of re-creating it. Thus your component won't re-render.
For example
// In LayerController
// this mutates the array, but won't trigger a render
layers.push(/* some new layer */);
onLayerChange(layers);
// creates a new array, which should trigger a render
const newLayer = {/* your new layer */};
const newLayers = [...layers, newLayer];
onLayerChange(newLayers)
Upvotes: 8