Select to view content in your preferred language

Basemaps are duplicated in BasemapGallery widget in ReactJS app

245
4
Jump to solution
08-15-2024 01:08 PM
bradMaps
Emerging Contributor

Hello,

I have a React 17 app utilizing 4.21 of the JS Maps SDK.  I am able to add the BasemapGallery widget with two basemaps, but the basemap tiles are duplicated 14 times.  Is there a hook I should be using to prevent the duplication?

Also, how can I force the gallery to display as 3 horizontal tiles per row, instead of just vertically?

Thanks!!

const BasemapGroup = ({
  label,
}: {
  label: string;
  children?: React.ReactNode;
}) => {
  const mapComponents = useContext(MapContext);
  const [open, setOpen] = useState(false);
  const classes = useStyles();

  const basemapGallery = new BasemapGallery({
    view: mapComponents.view,
    source: [Basemap.fromId("hybrid"), Basemap.fromId("gray")],
  });
  return (
    <Box mb={5} className={classes.layerGroupContainer}>
      <MetricLabelLight
        style={{ color: palette.blue, cursor: "pointer" }}
        onClick={() => {
          setOpen(!open);
        }}
      >
        {label}
      </MetricLabelLight>
      <Collapse in={true} timeout={500}>
        <div
          ref={(element) => element && (basemapGallery.container = element)}
        ></div>
      </Collapse>
    </Box>
  );
};

...

<BasemapGroup label="Basemaps" key="Basemaps"></BasemapGroup>

 

 

0 Kudos
1 Solution

Accepted Solutions
bradMaps
Emerging Contributor

useEffect/useRef fixed it!

 

For anyone interested, here's the new code:

const BasemapGroup = ({
  label,
}: {
  label: string;
  children?: React.ReactNode;
}) => {
  const mapComponents = useContext(MapContext);
  const [open, setOpen] = useState(false);
  const classes = useStyles();

  const basemapGalleryRef = useRef<BasemapGallery | null>(null);

  useEffect(() => {
    mapComponents.view.when(() => {
      basemapGalleryRef.current = new BasemapGallery({
        view: mapComponents.view,
        source: [Basemap.fromId("hybrid"), Basemap.fromId("gray")],
      });
    });
  }, [mapComponents.view]);

  const basemapGallery = basemapGalleryRef.current;

  return (
    <Box mb={5} className={classes.layerGroupContainer}>
      <MetricLabelLight
        style={{ color: palette.blue, cursor: "pointer" }}
        onClick={() => {
          setOpen(!open);
        }}
      >
        {label}
      </MetricLabelLight>
      <Collapse in={true} timeout={500}>
        <div
          ref={(element) =>
            element && basemapGallery && (basemapGallery.container = element)
          }
        ></div>
      </Collapse>
    </Box>
  );
};

 

Any tips on forcing the gallery to display as 3 horizontal tiles per row, instead of just vertically?  It seems that if the width is > 450px, it should show as 3 tiles per row.

Thanks again!

View solution in original post

0 Kudos
4 Replies
bradMaps
Emerging Contributor

@ReneRubalcava curious if you have any ideas for troubleshooting.  Thanks!!

0 Kudos
ReneRubalcava
Honored Contributor

Tough to tell from snippet, if you have a git repo or stackblitz, might be able to tell.

You probably don't want to assign the BasemapGallery container directly, do it in a useEffect with a useRef with some guards against nulls and stuff.

Does this happen in dev mode and prod? HMR can do this sometimes.

0 Kudos
bradMaps
Emerging Contributor

Thanks for taking a look.  Unfortunately, the code is private, so I can't share the repo.  I will look into creating a stackblitz if I'm still stuck after trying your suggestions.  I just ran a build and it is still showing the basemaps repeated, so I don't think HMR is the culprit.

 

Thanks again!

bradMaps_0-1724181018350.png

 

0 Kudos
bradMaps
Emerging Contributor

useEffect/useRef fixed it!

 

For anyone interested, here's the new code:

const BasemapGroup = ({
  label,
}: {
  label: string;
  children?: React.ReactNode;
}) => {
  const mapComponents = useContext(MapContext);
  const [open, setOpen] = useState(false);
  const classes = useStyles();

  const basemapGalleryRef = useRef<BasemapGallery | null>(null);

  useEffect(() => {
    mapComponents.view.when(() => {
      basemapGalleryRef.current = new BasemapGallery({
        view: mapComponents.view,
        source: [Basemap.fromId("hybrid"), Basemap.fromId("gray")],
      });
    });
  }, [mapComponents.view]);

  const basemapGallery = basemapGalleryRef.current;

  return (
    <Box mb={5} className={classes.layerGroupContainer}>
      <MetricLabelLight
        style={{ color: palette.blue, cursor: "pointer" }}
        onClick={() => {
          setOpen(!open);
        }}
      >
        {label}
      </MetricLabelLight>
      <Collapse in={true} timeout={500}>
        <div
          ref={(element) =>
            element && basemapGallery && (basemapGallery.container = element)
          }
        ></div>
      </Collapse>
    </Box>
  );
};

 

Any tips on forcing the gallery to display as 3 horizontal tiles per row, instead of just vertically?  It seems that if the width is > 450px, it should show as 3 tiles per row.

Thanks again!

0 Kudos