Reactjs 初始设置后使用状态未设置
我有一个功能组件正在使用Reactjs 初始设置后使用状态未设置,reactjs,react-hooks,react-google-maps,Reactjs,React Hooks,React Google Maps,我有一个功能组件正在使用useState,并使用@react google maps/api组件。我有一个映射,它使用onLoad函数初始化映射上的自定义控件(使用click事件)。然后,我在此单击事件中设置状态。它第一次工作,但每次之后都不会切换值 功能组件: import React, { useCallback } from 'react'; import { GoogleMap, LoadScript } from '@react-google-maps/api'; export de
useState
,并使用@react google maps/api
组件。我有一个映射,它使用onLoad函数初始化映射上的自定义控件(使用click事件)。然后,我在此单击事件中设置状态。它第一次工作,但每次之后都不会切换值
功能组件:
import React, { useCallback } from 'react';
import { GoogleMap, LoadScript } from '@react-google-maps/api';
export default function MyMap(props) {
const [radiusDrawMode, setRadiusDrawMode] = React.useState(false);
const toggleRadiusDrawMode = useCallback((map) => {
map.setOptions({ draggableCursor: (!radiusDrawMode) ? 'crosshair' : 'grab' });
setRadiusDrawMode(!radiusDrawMode);
}, [setRadiusDrawMode, radiusDrawMode]); // Tried different dependencies.. nothing worked
const mapInit = useCallback((map) => {
var radiusDiv = document.createElement('div');
radiusDiv.index = 1;
var radiusButton = document.createElement('div');
radiusDiv.appendChild(radiusButton);
var radiusText = document.createElement('div');
radiusText.innerHTML = 'Radius';
radiusButton.appendChild(radiusText);
radiusButton.addEventListener('click', () => toggleRadiusDrawMode(map));
map.controls[window.google.maps.ControlPosition.RIGHT_TOP].push(radiusDiv);
}, [toggleRadiusDrawMode, radiusDrawMode, setRadiusDrawMode]); // Tried different dependencies.. nothing worked
return (
<LoadScript id="script-loader" googleMapsApiKey="GOOGLE_API_KEY">
<div className="google-map">
<GoogleMap id='google-map'
onLoad={(map) => mapInit(map)}>
</GoogleMap>
</div>
</LoadScript>
);
}
import React,{useCallback}来自“React”;
从'@react google maps/api'导入{GoogleMap,LoadScript};
导出默认函数MyMap(道具){
const[radiusDrawMode,setRadiusDrawMode]=React.useState(false);
const toggleRadiusDrawMode=useCallback((映射)=>{
setOptions({draggableCursor:(!radiusDrawMode)?'crosshair':'grab'});
setRadiusDrawMode(!radiusDrawMode);
},[setRadiusDrawMode,radiusDrawMode]);//尝试了不同的依赖项。没有任何效果
const mapInit=useCallback((map)=>{
var radiusDiv=document.createElement('div');
半径指数=1;
var radiusButton=document.createElement('div');
RadiusIV.appendChild(radiusButton);
var radiusText=document.createElement('div');
radiusText.innerHTML='Radius';
radiusButton.appendChild(radiusText);
radiusButton.addEventListener('单击',()=>切换RadiusDrawMode(映射));
map.controls[window.google.maps.ControlPosition.RIGHT\u TOP].push(radiusDiv);
},[toggleRadiusDrawMode,radiusDrawMode,setRadiusDrawMode];//尝试了不同的依赖项。没有任何效果
返回(
mapInit(地图)}>
);
}
用户第一次按下地图上的按钮时,会将radiudsrawmode
设置为true
,并为地图设置正确的光标(十字线)。之后每次单击按钮都不会更新radiusDrawMode
,并保持在true
状态
非常感谢您的帮助。我想这是
useCallback
的缓存问题。尝试删除useCallback
s以在不进行优化的情况下进行测试。如果它有效,你肯定会知道,然后你可以再次检查哪些应该被记住,哪些可能不应该
首先,我将从toggleRadiusDrawMode
中删除一个:
const toggleRadiusDrawMode = map => {
map.setOptions({ draggableCursor: (!radiusDrawMode) ? 'crosshair' : 'grab' });
setRadiusDrawMode(!radiusDrawMode);
};
另外,您是否可以访问map
选项(您正在使用map.setOptions
设置的选项)的状态?如果是这样的话,使用地图选项的实际状态,而不是创建自己的内部状态来跟踪同一事物,可能是值得的。比如(我不确定它是否是map.options
):
另外,我怀疑这是问题所在,但看起来您在
元素上缺少了一个结束括号?(另外,您可能不需要在onLoad
和mapInit
之间创建中间函数,并且可以将mapInit
直接传递到onLoad
)
这是我最后用来解决这个问题的解决方案 对于
setRef(false)
,我基本上必须使用useState(false)
来切换。然后设置useEffect以监听ref上的更改,并在实际的切换RadiudDraw
中设置触发useEffect
的参考值以设置实际的ref值
import React, { useCallback, useRef } from 'react';
import { GoogleMap, LoadScript } from '@react-google-maps/api';
export default function MyMap(props) {
const radiusDrawMode = useRef(false);
let currentRadiusDrawMode = radiusDrawMode.current;
useEffect(() => {
radiusDrawMode.current = !radiusDrawMode;
});
const toggleRadiusDrawMode = (map) => {
map.setOptions({ draggableCursor: (!currentRadiusDrawMode) ? 'crosshair' : 'grab' });
currentRadiusDrawMode = !currentRadiusDrawMode;
};
const mapInit = (map) => {
var radiusDiv = document.createElement('div');
radiusDiv.index = 1;
var radiusButton = document.createElement('div');
radiusDiv.appendChild(radiusButton);
var radiusText = document.createElement('div');
radiusText.innerHTML = 'Radius';
radiusButton.appendChild(radiusText);
radiusButton.addEventListener('click', () => toggleRadiusDrawMode(map));
map.controls[window.google.maps.ControlPosition.RIGHT_TOP].push(radiusDiv);
});
return (
<LoadScript id="script-loader" googleMapsApiKey="GOOGLE_API_KEY">
<div className="google-map">
<GoogleMap id='google-map'
onLoad={(map) => mapInit(map)}>
</GoogleMap>
</div>
</LoadScript>
);
}
import React,{useCallback,useRef}来自“React”;
从'@react google maps/api'导入{GoogleMap,LoadScript};
导出默认函数MyMap(道具){
const radiusDrawMode=useRef(false);
让currentRadiusDrawMode=radiusDrawMode.current;
useffect(()=>{
radiusDrawMode.current=!radiusDrawMode;
});
常量toggleRadiusDrawMode=(映射)=>{
setOptions({draggableCursor:(!currentRadiusDrawMode)?'crosshair':'grab'});
currentRadiusDrawMode=!currentRadiusDrawMode;
};
常量mapInit=(映射)=>{
var radiusDiv=document.createElement('div');
半径指数=1;
var radiusButton=document.createElement('div');
RadiusIV.appendChild(radiusButton);
var radiusText=document.createElement('div');
radiusText.innerHTML='Radius';
radiusButton.appendChild(radiusText);
radiusButton.addEventListener('单击',()=>切换RadiusDrawMode(映射));
map.controls[window.google.maps.ControlPosition.RIGHT\u TOP].push(radiusDiv);
});
返回(
mapInit(地图)}>
);
}
不确定这是否是处理此问题的最佳方法,但希望它能在将来帮助其他人。感谢您的快速回复。但上述措施都不起作用。我很确定这和eventListener的范围有关,但不确定是什么。
<GoogleMap id='google-map'
onLoad={mapInit}>
import React, { useCallback, useRef } from 'react';
import { GoogleMap, LoadScript } from '@react-google-maps/api';
export default function MyMap(props) {
const radiusDrawMode = useRef(false);
let currentRadiusDrawMode = radiusDrawMode.current;
useEffect(() => {
radiusDrawMode.current = !radiusDrawMode;
});
const toggleRadiusDrawMode = (map) => {
map.setOptions({ draggableCursor: (!currentRadiusDrawMode) ? 'crosshair' : 'grab' });
currentRadiusDrawMode = !currentRadiusDrawMode;
};
const mapInit = (map) => {
var radiusDiv = document.createElement('div');
radiusDiv.index = 1;
var radiusButton = document.createElement('div');
radiusDiv.appendChild(radiusButton);
var radiusText = document.createElement('div');
radiusText.innerHTML = 'Radius';
radiusButton.appendChild(radiusText);
radiusButton.addEventListener('click', () => toggleRadiusDrawMode(map));
map.controls[window.google.maps.ControlPosition.RIGHT_TOP].push(radiusDiv);
});
return (
<LoadScript id="script-loader" googleMapsApiKey="GOOGLE_API_KEY">
<div className="google-map">
<GoogleMap id='google-map'
onLoad={(map) => mapInit(map)}>
</GoogleMap>
</div>
</LoadScript>
);
}