首页 > 解决方案 > 反应原生时未安装的组件错误

问题描述

警告错误:无法对未安装的组件执行反应状态更新。

这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和同步任务。

捕获位置后,我正在使用它导航到不同的场景。但它在导航到屏幕后显示警告

useEffect ( () => {
        (async () => {
            let {status} = await Location.requestPermissionsAsync();

            if (status !== 'granted'){
                setErrorMsg('Permission to access location is not granted')
            }
            let location = await Location.getCurrentPositionAsync({});

            const {coords} = location

            if (coords) {

                const {latitude, longitude} = coords;

                let addressResponse: any = await Location.reverseGeocodeAsync({latitude, longitude})

                for (let item of addressResponse){
                    setAddress(item)
                    let currentAddress = `${item.name},${item.street},${item.postalCode},${item.country}`
                    setDisplayAddress (currentAddress)

                    if (currentAddress.length>0){
                                                setTimeout(
                            () => {
                                navigate('homeStack')
                            },1000) 
                        }
                    
                      return;
                }
                
            }else {
                
            }
        })();
},)

标签: typescriptreact-native

解决方案


您应该在调用 setState 之前检查组件是否仍然挂载,最简单的方法是引入一个标志变量isMounted,您将在每次异步函数调用后检查该变量。

function Component() {
 let isMounted= true;
 useEffect ( () => {
   (async () => {
        let {status} = await Location.requestPermissionsAsync();

        if(!isMounted) return; // stop the execution of the function;

        if (status !== 'granted'){
            setErrorMsg('Permission to access location is not granted')
        }
        let location = await Location.getCurrentPositionAsync({});

        if(!isMounted) return; // stop the execution of the function;
      // ...
   })
 return ()=> (isMounted= false);
}

或者,如果组件卸载,您可以使用自定义的实验性钩子自动取消异步序列:

import React, { useState } from "react";
import { useAsyncEffect } from "use-async-effect2";
import { CPromise } from "c-promise2";

export default function TestComponent(props) {
  // ...
  useAsyncEffect(function* () {
    const { status } = yield Location.requestPermissionsAsync();

    if (status !== "granted") {
      setErrorMsg("Permission to access location is not granted");
    }

    const { coords } = yield Location.getCurrentPositionAsync({});

    if (coords) {
      const { latitude, longitude } = coords;

      let addressResponse = yield Location.reverseGeocodeAsync({
        latitude,
        longitude
      });

      for (let item of addressResponse) {
        setAddress(item);
        let currentAddress = `${item.name},${item.street},${item.postalCode},${item.country}`;
        setDisplayAddress(currentAddress);

        if (currentAddress.length > 0) {
          yield CPromise.delay(1000); // auto-cancellable delay
          navigate("homeStack");
        }

        return;
      }
    }
  });
}

推荐阅读