Mike Hemilton
Mike Hemilton

Reputation: 111

React leaflet: How to update positions to polygon

I'm trying to make a polygon which can get updated by click.

I made a polygon that contains an array of coordinates in its position definition, and I did this function called change() that is supposed to push the new coordinates into the array.

The problem is that as soon as I launch the app it just puts in the new coordinates even before I press the button

I became acquainted with a question asked here about how to make a live update for a polygon, and this question received an answer that shows how to do something similar that is quite close to it.

The problem is that the respondent there uses the class someFunction extends React.Component {} method, while im setting up my main function like this: export default function App() So now I want to know now how I can use the same method only in the "normal" form of the main function.

I also found other suggestions which used for other cases and non of them worked for me.

Here's the code:

import 'leaflet/dist/leaflet.css';
import {MapContainer, TileLayer, Polygon} from 'react-leaflet';

const polygon1 = [
  [51.515, -0.09],
  [51.52, -0.1],
  [51.52, -0.12],
]

const polygon2 = [
  [51.535, -0.14],
  [51.54, -0.13],
  [51.53, -0.125],
]

const positions = [polygon1];

function change () {
  positions.push(polygon2);
}


export default function Example() {

  const classes = useStyles();

  return (
    <div>
    
    <MapContainer center={position} zoom={13} className={classes.map}>
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
    <Polygon color={'purple'} positions={positions} />
    </MapContainer>
    <Button onClick={change()}>Add Polygon</Button>
    </div>
  )
}

Upvotes: 0

Views: 1615

Answers (1)

kboul
kboul

Reputation: 14600

It seems you are not familiar with React judging from the code you have provided

if you pass change() this will be immediately be invoked and will mutate the state by pushing to positions variable that is the reason you are seeing the two polygons drawn on the map when the page lands

<Button onClick={change()}>Add Polygon</Button>

Instead what you should do is:

  1. Store positions in a state variable
  2. Change positions without mutating the variable by copying it
  3. pass a reference to onClick callback

Therefore you should have

export default function Map() {
  const [positions, setPositions] = useState([polygon1]);

  function handleClick() {
    setPositions((prevPositions) => [...prevPositions, polygon2]);
  }

  return (
    <div>
      <MapContainer center={[51.515, -0.09]} zoom={13} style={mapStyle}>
        <TileLayer
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <Polygon color={"purple"} positions={positions} />
      </MapContainer>
      <button onClick={handleClick}>Add Polygon</button>
    </div>
  );
} 

Demo

Upvotes: 1

Related Questions