我正在创建一个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显示正确的值。
答案 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])