未在Google Maps侦听器中更新React状态

时间:2019-05-31 14:06:44

标签: reactjs google-maps-api-3

我正在创建一个Google Maps React应用程序,可以在其中创建,编辑和删除对象,然后再映射。 当我按下标记时,谷歌地图点击侦听器将以我可以编辑的形式显示其数据。如果我确实开始编辑表单中的数据,则将“ isEditingMapObject”状态设置为true。这是通过useContext完成的。

现在,我的目标是阻止其他单击侦听器在“ isEditingMapObject”状态为true时运行其代码。我认为使用if检查将很容易。但是似乎单击侦听器的“ isEditingMapObject”状态永远不会改变。它将始终保持为假。

const Markers = ({ googleMap, map }) => {
    const mapContext = useContext(MapContext);

    const mapMarkerReducer = (state, action) => {
        switch (action.type) {
            case "ADD":
                return state.concat(action.payload.marker);
            case "UPDATE":
                return state.filter(marker => marker._id !== action.payload._id).concat(action.payload.marker);
            case "SET":
                return action.payload;
            case "REMOVE":
                return state.filter(marker => marker._id !== action.payload._id);
            default:
                return state;
        }
    }
    const [markers, markersDispatch] = useReducer(mapMarkerReducer, []);

    useEffect(() => {
        if (!googleMap || !map) {
            return;
        }
        axios
            .get(constants.API_MARKERS)
            .then(result => {
                console.log("success");
                const markersLoaded = [];
                for (const marker of result.data) {
                    const iconPath = marker.type == "info" ? iconImportant : iconMailbox;
                    const markerObj = new googleMap.maps.Marker({
                        zIndex: 115,
                        position: { lat: marker.latitude, lng: marker.longitude },
                        icon: {
                            url: iconPath,
                            scaledSize: new googleMap.maps.Size(15, 15)
                        },
                        type: "marker",
                        marker: marker,
                        map: map,
                        visible: mapContext.markersIsVisible
                    });
                    googleMap.maps.event.addListener(markerObj, "click", (marker) => {
                        if(mapContext.isEditingMapObject) {
                            return;
                        }
                        mapContext.setActiveMapObjectHandler(marker);
                    });
                    markersLoaded.push(markerObj)
                }
                markersDispatch({ type: "SET", payload: markersLoaded });
            })
            .catch(error => {
                console.log(error.response);
            });
    }, [googleMap, map]);
    return null
};

export default Markers;

我希望当mapContext.isEditingMapObject的状态为true时,如果if语句触发返回。但是,在侦听器内部始终是错误的。在侦听器外部记录状态时,mapContext.isEditingMapObject显示正确的值。

1 个答案:

答案 0 :(得分:0)

地图侦听器在声明时正在存储状态。并且与反应状态所引用的对象不同。因此,反应状态的任何更改都不会影响侦听器。

解决方法是在触发列表器时更新反应状态。然后使用useEffect触发该状态更改。然后我在那里访问当前的反应状态。它不漂亮!我没有找到其他可行的解决方案:

const [clickedMapObjectEvent, setClickedMapObjectEvent] = useState(null);

googleMap.maps.event.addListener(markerObj, "click", (marker) => {
   //Can not access react state in here
   setClickedMapObjectEvent(marker);
});

useEffect(() => {
   //Access state in here
}, [clickedMapObjectEvent])