Courlu
Courlu

Reputation: 96

React 16.8 hooks - child component won't re-render after updating parent state

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

Answers (1)

Scarysize
Scarysize

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

Related Questions