0

Inside useEffect, the useState Boolean value does not change. Please help me. I'm trying to make a modal window pop up when a marker is clicked in the openlayers map. Since the openlayers map is executed inside useEffect, the marker click event must also be inside useEffect, but even if setState is executed, a boolean value does not come out. When debugging, it is confirmed that the boolean value has changed, but when taking a console.log, the value does not change and the modal window does not appear. Please help me.

function App() {
  const [mapObject, setMapObject] = useState({});
  const [modalState, setModalState] = useState(false);

  useEffect(() => {
    const map = new OlMap({
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
      ],
      target: "map",

      view: new View({
        center: fromLonLat([126.752, 37.4713]),
        zoom: 7,
        minZoom: 3,
        maxZoom: 17,
      }),
    });

    jsondata.forEach((dataPoint) => {
      const { lat, log } = dataPoint;

      const coordinate = fromLonLat([lat, log]);

      const markerFeature = new Feature({
        geometry: new Point(coordinate),
      });

      const markerStyle = new Style({

      });

      const vectorLayer = new VectorLayer({
        source: new VectorSource(),
      });

      markerFeature.setStyle(markerStyle);
      vectorLayer.getSource().addFeature(markerFeature);

      map.addLayer(vectorLayer);

      // const handleMarkerClick = (event) => {
      //   setModalState(true);
      // };

      const handleMarkerClick = () => {
        setModalState((modalState) => !modalState);
        console.log("핸들러에서 모달 : " + modalState);
      };

      map.on("click", function (event) {
        var feature = map.forEachFeatureAtPixel(
          event.pixel,
          function (feature) {
            return feature;
          }
        );
        if (feature === markerFeature) {
          handleMarkerClick();
          console.log("modalState : " + modalState);
        }
      });
    });


    setMapObject({ map });

    return () => {
      map.setTarget(null);
      setMapObject(null);
    };
  }, []);

  return (
    <div>
      {/* <Modal modalProps={modalState}>
      </Modal> */}
      
      {modalState && (
        <ReactModal>
          <button onClick={() => setModalState(false)}>닫기</button>
        </ReactModal>
      )}
    </div>
  );
}

I'm trying to make a modal window pop up when a marker is clicked in the openlayers map.

youngha
  • 1
  • 1
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Jul 26 '23 at 02:26
  • pls try to put ``` state data ``` as a dependency of useEffect. ``` useEffect(() => { ... your logic here }, [modalState]); ``` – Yewin Jul 26 '23 at 02:42
  • Please make it clear: Delete unnecessary code, and what name of "the useState Boolean value" – DinhNguyen Jul 26 '23 at 02:43

1 Answers1

1
function App() {
  const modalStateRef = useRef()
  const [modalState, setModalState] = useState(false);
  modalStateRef.current = modalState;

  useEffect(() => {
    // ...
    
    map.on("click", function (event) {
      var feature = map.forEachFeatureAtPixel(
        event.pixel,
        function (feature) {
          return feature;
        }
      );
      if (feature === markerFeature) {
        handleMarkerClick();
        /*  everywhere inside `useEffect`,
         * replace `modalState` with `modalStateRef.current`
         */
        console.log("modalState : " + modalStateRef.current);
      }
    });
  }, [])
  
  // ...
}

This is a classic "React stale closure" problem. You can resolve it with useRef hook. See my other answer for more in-depth explanation why useRef works

hackape
  • 18,643
  • 2
  • 29
  • 57