0

I am trying to update a marker's title (tooltip content when mouse hovers over...) dynamically, however that field stays stuck at what it was upon init.

Here is a simplified test case:

// @flow
import {
    Box, Button
} from '@material-ui/core'
import React, { useState } from 'react';
import { Map, TileLayer, Marker } from 'react-leaflet'
import "leaflet/dist/leaflet.css"
import L from 'leaflet';
import icon from 'leaflet/dist/images/marker-icon.png';

let DefaultIcon = L.icon({ iconUrl: icon });
L.Marker.prototype.options.icon = DefaultIcon;

function Test(props) {
    const [mstate, setMstate] = useState(false)
    const [mlong, setMlong] = useState(13)
    // let mlong = (mstate) ? 13.047 : 13

    const flipMstate = () => {
        setMstate(!mstate)
        setMlong((mstate)? 13 : 13.047)
    }

    return (
        <Box component='div' style={{ width: '80%', height: '80%', position: 'relative', }}>
            <Button onClick={flipMstate} style={{ height: '10%' }} >
                Change marker
            </Button>
            <Map
                preferCanvas={true}
                style={{ height: '90%' }}
                center={[50.63, 13.047]}
                zoom={13}
                minZoom={3}
                maxZoom={18}
            >
                <TileLayer
                    attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?"
                />
                <Marker
                    title={mlong}
                    position={[50.63, mlong]}
                />
            </Map>
        </Box>
    )
}

export default Test

When clicking on the button, the marker moves, as it should. But if you hover on the marker, the tooltip will always display "13". Looking at the debugger shows that the "title" field gets updated correctly. If I modify the code to start in the other state, the tooltip display will always be 13.047

Am I doing anything wrong?

kboul
  • 13,836
  • 5
  • 42
  • 53
Will59
  • 1,430
  • 1
  • 16
  • 37

2 Answers2

2

Use react-leaflet's Tooltip to achieve the desired behavior

 <Marker position={[50.63, mlong]}>
     <Tooltip direction="top" offset={[10, 0]}>
       {mlong}
     </Tooltip>
 </Marker>

Demo

kboul
  • 13,836
  • 5
  • 42
  • 53
  • Thanks a lot for the answer. That would indeed do it, but I'm more looking for the root cause, not so much a work around (feeling uneasy about something so basic not working, and wondering if something is really wrong in my approach, or if I simply stumbled on a bug). – Will59 Dec 05 '19 at 17:17
  • 2
    I am not sure whether you can do this otherwise (please if anyone knows another way, share with us) because if you look [here](https://github.com/PaulLeCam/react-leaflet/blob/master/src/Marker.js#L26) on `updateLeafletElement` which is responsive and triggers props' update when passed props change there is no case for `title` because there is no native Leaflet method to change the title. For instance, to change the marker's icon property which is a prop in the react-leaflet component `setIcon` method is called which is a native leaflet method after comparing previous icon prop with current. – kboul Dec 05 '19 at 18:21
0

The settter of useState hook does not change your value immediately. So when you are calling setMlong((mstate)? 13 : 13.047) you are not using the updated mstate value, but the old one.

Try to add useEffect hook and handle dependend state there:

useEffect(() => {
    setMlong((mstate)? 13 : 13.047)
}, [mstate]);

Or look at another solution in answer to this question:

useState set method not reflecting change immediately

lavor
  • 1,787
  • 1
  • 14
  • 21
  • Thanks for the answer. My intent in this example is indeed to use the "old" or previous version of mstate in this test logic, so all is as intended. My "mstate" value does flip between 13 and 13.047. But this doesn't reflect in the Marker tooltip, only in its location. – Will59 Dec 05 '19 at 14:43