0

Problem

I am using leaflet-contextmenu v1.4.0 in react-leaflet v3.2.1. The problem is with my code below is that showColor never updates when color changes.

For example, if color is 'blue' at app initialization, showColor will know color is 'blue'. If color changes to 'red', showColor never updates; it seems to be immutable.

Question

How can I update callbacks within leaflet-contextmenu menu items?

const Component = ({ color: string }) => {
  var map = L.map('map', {
    contextmenu: true,
    contextmenuWidth: 140,
    contextmenuItems: [
      {
        text: 'Show color',
        callback: showColor,
      },
    ],
  });
  
  function showColor() {
    alert(color);
  }
};

RouteMapper
  • 2,484
  • 1
  • 26
  • 45
  • where is `color` defined? the on in the `Component` is out of scope for the `showColor` function. So `color` in `showColor` must refer to a different variable of the same name defined somewhere else. – Christian Fritz Oct 09 '21 at 18:18
  • @ChristianFritz - I updated my post to put it in scope. That was a typo. – RouteMapper Oct 09 '21 at 18:32
  • Some react-leaflet components need to have their `key` updated when the data changes, or else they do not update reactively. See https://stackoverflow.com/a/44221724/1087119. – Christian Fritz Oct 09 '21 at 22:07
  • Can you change `text: 'Show color'` to `text: color` and see if the context menu item text changes when color updates. If not, my guess is that you can only call `L.map` once on the #map element and all future calls are ignored – teddybeard Oct 10 '21 at 02:39

1 Answers1

1

I think you can only instantiate the map once, not on every re-render. Instead, just add the context menu item on each re-render.

// Only invoke L.map() once
var map = L.map('map', {
    contextmenu: true,
    contextmenuWidth: 140,
});

const Component = ({ color: string }) => {

    // update context menu items anytime color changes
    useEffect(() => {
        map.contextmenu.removeAllItems();
        map.contextmenu.addItem({
          text: 'Show color',
          callback: () => { alert(color) },
        });
    }, [color]);
};
teddybeard
  • 1,964
  • 1
  • 12
  • 14