menu

Questions & Answers

how to re render my ReplayMap component when select value changes?

right now I have a map component which plots polyline data based on the value selected from my select menu component right now. The issue I am having is that when I change the value to a different option in my select menu and click the button to play the animation (note the button plays and pauses so will need to click until new play again) again it seems to still have the previous data stored within and so will plot one polyline for previous option chosen then one polyline for the new data selected. Where as I want it so that when the select menu value is changed the data is cleared and just stores the current selected and then will plot only the value selected. I cannot seem to figure it out been at this for a while now would appreciate some help.

I have created a sandbox to run the program. There may be some CSS issues with the map seems patchy not sure why that is as it works on my application. I would appreciated if anyone can solve my issue mentioned with the select menus

link to code: https://codesandbox.io/s/distracted-sun-jwk3dg?file=/src/ReplayMap.js

Answers(1) :

If you want to render after you choise you can add key your component like the below.

import React, { useContext, useState, useEffect, useRef } from "react";

import {
  MapContainer,
  TileLayer,
  Popup,
  Polyline,
  Marker
} from "react-leaflet";
import MovingMarker from "./MovingMarker";
import ActivityList from "./ActivityList";

let setPositionInterval;

function ReplayMap(props) {
  const [mapRef, setMapRef] = useState(1); // added this line for trigger counter
  const [nextPosition, setNextPosition] = useState();
  const currentIdxRef = useRef(0);
  const duration = 0.2 * 1000; // 1 second is 1000ms

  useEffect(() => {
    if (props.playStatus) {
      setPositionInterval = setInterval(() => {
        currentIdxRef.current < props.activityData.length &&
          setNextPosition(props.activityData[currentIdxRef.current]);
        setMapRef(mapRef++); // added this line if position change your counter increse and force re-render your component.
        currentIdxRef.current = currentIdxRef.current + 1;
      }, duration);

      return () => {
        clearInterval(setPositionInterval);
      };
    }
  }, [props.playStatus]);

  //console.log("Props = ", props.activityData);
  return (
    <div>
      <MapContainer
        center={[-8.798064, 115.222211]}
        zoom={15}
        scrollWheelZoom={false}
        style={{ width: "400px", height: "400px" }}
        key={mapRef.toString()}
      >
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url={"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"}
        />
        {props.playStatus && (
          <MovingMarker
            nextPosition={nextPosition ? nextPosition : props.activityData[0]}
            duration={duration}
            playStatus={props.playStatus}
          />
        )}
      </MapContainer>
    </div>
  );
}

export default ReplayMap;

Comments:
2023-01-23 23:10:10
this is not what I specified I want the map to re render after the select value changes, not everytime my polyline function is called?
2023-01-23 23:10:10
I want the map to re render when the select value changes
2023-01-23 23:10:10
I added new version your map is re render only change your selection. You can check this. if I understand correctly.
2023-01-23 23:10:10
this does still not work did you try actually running this in the sandbox i provided. The data that is being plotted should be empty when a new value is selected in the menu?
2023-01-23 23:10:10
why not trying to run the code inside the sandbox before posting?