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>
    );
}