visgl / visgl/react-map-gl

Issues with useControl when upgrading to nextjs 14.2

Open
#2,413 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
8.5k
Forks
1.4k
Avg merge
5d 17h
Merged PRs (30d)
3

Description

Description

I'm using an implementation that can be summed up as the following

<Map
        initialViewState={initialViewState}
        style={{ width: '100%', height: '100%' }}
        mapStyle="mapbox://styles/mapbox/satellite-streets-v12"
      >
        <DrawControl
          position="top-left"
          onCreate={onUpdate}
          onUpdate={onUpdate}
          onDelete={onDelete}
        />
</Map>

Where DrawControl looks something like...

import MapboxDraw from '@mapbox/mapbox-gl-draw';
import { useControl } from 'react-map-gl';

export default function DrawControl({
  onCreate = () => {},
  onUpdate = () => {},
  onDelete = () => {},
  ...props
}: DrawControlProps) {
  const [draw, setDraw] = useState<MapboxDraw | null>(null);
  useControl<MapboxDraw>(
    () => {
      const drawInstance = new MapboxDraw(props);
      setDraw(drawInstance);
      return drawInstance;
    },
    ({ map }) => {
      map.on('draw.create', onCreate);
      map.on('draw.update', onUpdate);
      map.on('draw.delete', onDelete);
    },
    ({ map }) => {
      map.off('draw.create', onCreate);
      map.off('draw.update', onUpdate);
      map.off('draw.delete', onDelete);
    },
    {
      position: props.position,
    }
  );

  useEffect(() => {
    if (!draw || !mapReady) return;
    const currentDrawings = draw.getAll();
}, [draw, someOtherVariableWeTrack]

We haven't had any issues with this implementation until upgrading to next 14.2. I've downgraded back to next 14.1 and confirmed that the issue is selective to next 14.2 for reasons I'm still trying to understand. The error I get is that draw.getAll() is undefined. Upon debugging, I can see that draw is indeed defined, along with some non-function attributes, but all the functions yield the same undefined error.

I have confirmed that this behavior happens even after the map is definitively loaded. I now have high confidence the issue is with the way I am storing drawInstance. From other posts online, it seems like this issue happens when the map is not yet loaded. However, I can confirm that the map is loaded and the draw control is present -- I can draw polygons on the map with no issues, but whenever I hit this useEffect, I always get the error, even once the map is loaded and I can confirm the ability to draw.

This is what leads me to believe it is something related to the way useControl is working, or at the very least is something related to the way that we're referencing the drawInstance.

Expected Behavior

In next 14.1, this works as expected. The expected behavior is to have access to the drawings that are currently on the map.

Steps to Reproduce

Can provide codesandbox if the description is not enough to understand the issue. Please let me know.

Environment
  • Framework version: react-map-gl@7.1.7
  • Map library: mapbox-gl@2.0.0 (tested with mapbox-gl@3.5.1 with same issue)
  • Next: 14.2 (all patch versions)
  • mapboxdraw: @mapbox/mapbox-gl-draw@1.4.3
  • Browser: Brave@1.67
  • OS: OSX 14.3.1
Logs
TypeError: Cannot read properties of undefined (reading 'getAll')
    at e.getAll (mapbox-gl-draw.js:1:77757)
    at eval (draw-control.tsx:50:34)
    at commitHookEffectListMount (react-dom.development.js:21102:1)
    at commitHookPassiveMountEffects (react-dom.development.js:23154:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23259:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23334:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23370:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)
    at commitPassiveMountOnFiber (react-dom.development.js:23256:1)
    at recursivelyTraversePassiveMountEffects (react-dom.development.js:23237:1)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the draw-control.tsx useControl callback and the useEffect that calls draw.getAll(); compare the behavior under Next 14.1 and 14.2 using the reported Mapbox Draw setup. A useful reproduction or test should establish why getAll is unavailable after the map loads, with done meaning the current drawings can be accessed reliably.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, react, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.