Search code examples
reactjsreact-state-managementreact-state

how to have set state for sibling component in React without updating


I have 2 sibling components in 1 parent component. It's like this:

import React, { useState } from 'react';
import PlaceSearchInput from './PlaceSearchInput';
import { GoogleMap, withGoogleMap } from "react-google-maps";

export default function Search(props) {
    const [mapCenter, setMapCenter] = useState({lat:3, lng:2});

    function Map() {

        return (
            <div>
            <GoogleMap defaultZoom={10} center={mapCenter}/>
            </div>
        )
    }

    const WrappedMap = withGoogleMap(Map);

    if (!props.isGoogleMapApiReady)
        return (
            <div>Loading...</div>
        )

    return (
        <div style={{ margin: "100px" }}>
           <div style={{ height: "50vh", width: "50vh" }}>
                <WrappedMap
                    loadingElement={<div style={{ height: "100%" }} />}
                    containerElement={<div id="map" style={{ height: "100%" }} />}
                    mapElement={<div style={{ height: "100%" }} />}
                />
                <PlaceSearchInput setMapCenter={setMapCenter} />
            </div>
        </div>
    )
}

I want Input sets coordinates and Map shows the coordinates. I know one way is that having coordinates state in parent and then passing set function to Input, coordinates to Map. But with this way I found out it whenever state is changed by Input component, though Map does move to new coordinates, Map is refreshed and that is what I want to avoid. Is there way to solve it?


Solution

  • Try this, I moved Map and WrappedMap's creation out of the of the Search component. I believe that the change in the component definition every time the component re-rendered likely caused react to think it's an entirely new component and unmount the old and mount the new rather than re-render.

    import React, { useState } from 'react';
    import PlaceSearchInput from './PlaceSearchInput';
    import { GoogleMap, withGoogleMap } from 'react-google-maps';
    
    function Map({ center }) {
      return (
        <div>
          <GoogleMap defaultZoom={10} center={center} />
        </div>
      );
    }
    
    const WrappedMap = withGoogleMap(Map);
    
    export default function Search(props) {
      const [mapCenter, setMapCenter] = useState({ lat: 3, lng: 2 });
    
      if (!props.isGoogleMapApiReady) {
        return <div>Loading...</div>;
      }
      return (
        <div style={{ margin: '100px' }}>
          <div style={{ height: '50vh', width: '50vh' }}>
            <WrappedMap
              loadingElement={<div style={{ height: '100%' }} />}
              containerElement={<div id="map" style={{ height: '100%' }} />}
              mapElement={<div style={{ height: '100%' }} />}
              center={mapCenter}
            />
            <PlaceSearchInput setMapCenter={setMapCenter} />
          </div>
        </div>
      );
    }