使用 navigator.geolocation.watchPosition 时 React 中的无限循环

Posted

技术标签:

【中文标题】使用 navigator.geolocation.watchPosition 时 React 中的无限循环【英文标题】:Infinte Loop in React while using navigator.geolocation.watchPosition 【发布时间】:2020-12-31 02:55:09 【问题描述】:

所以我试图获取用户的位置并将其存储在React.State 中。我有一个设置页面,用户可以通过按下按钮将settings.positionAllowed 设置为truefalse,false 是默认值。直到按下按钮,一切正常。但是一旦用户将设置设置为 true 并返回主页,就会创建一个无限循环,并且应用程序会在一段时间后崩溃。我首先想到的原因是每次重新渲染组件时都会创建一个navigator.geolovation.watchPosition 的实例。但是效果挂钩也没有解决问题。

这是我的代码:

navigator.geolocation ? let posObj = positionAllowed: false : let posObj = positionAllowed: true;

const [settings, setSettings] = useState(posObj);
useEffect(() => 
    if(settings.positionAllowed&&navigator.geolocation)
        let geolocation = navigator.geolocation.watchPosition((rawPosition)=>
            let positionData = 
                positionAvailable: true,
                    data: rawPosition
                
                if(positionData!=position)
                    setPosition(positionData);
                
            ,(err)=>
                console.log(err);
            ,
                enableHighAccuracy: true,
                maximumAge: 10000
            );
        
    
);

【问题讨论】:

【参考方案1】:

您需要将 [] 作为useEffect 的第二个参数传递。然后,它将像类组件中的componentDidMount() 一样工作。除非,每次状态更新都会被调用,会无限循环。

navigator.geolocation ? let posObj = positionAllowed: false : let posObj = positionAllowed: true;

const [settings, setSettings] = useState(posObj);
useEffect(() => 
    if(settings.positionAllowed&&navigator.geolocation)
        let geolocation = navigator.geolocation.watchPosition((rawPosition)=>
            let positionData = 
                positionAvailable: true,
                    data: rawPosition
                
                if(positionData!=position)
                    setPosition(positionData);
                
            ,(err)=>
                console.log(err);
            ,
                enableHighAccuracy: true,
                maximumAge: 10000
            );
        
    
, []);  // <---------------------------------

【讨论】:

【参考方案2】:

这是因为你的 useEffect 每次渲染都在运行。您需要添加一个依赖数组。如果你使用一个空白的依赖数组,它只会在第一次渲染时运行。

这可能有助于您更好地理解它。 [https://medium.com/better-programming/understanding-the-useeffect-dependency-array-2913da504c44][1]

navigator.geolocation ? let posObj = positionAllowed: false : let posObj = positionAllowed: true;

const [settings, setSettings] = useState(posObj);
useEffect(() => 
    if(settings.positionAllowed&&navigator.geolocation)
        let geolocation = navigator.geolocation.watchPosition((rawPosition)=>
            let positionData = 
                positionAvailable: true,
                    data: rawPosition
                
                if(positionData!=position)
                    setPosition(positionData);
                
            ,(err)=>
                console.log(err);
            ,
                enableHighAccuracy: true,
                maximumAge: 10000
            );
        
    
, []);

【讨论】:

以上是关于使用 navigator.geolocation.watchPosition 时 React 中的无限循环的主要内容,如果未能解决你的问题,请参考以下文章

navigator.geolocation 给出错误的结果

html5-geolocation : navigator.geolocation.watchPosition 连续回调

带有 navigator.geolocation.watchPosition 的连续标记

Cordova geolocation navigator.geolocation.getCurrentPosition 错误的窗口访问位置

在 Map 和 navigator.geolocation 上使用 Leaflet 的多个事件

传单地图:使用 navigator.geolocation.watchPosition 更新标记?