typescript - 反应原生时未安装的组件错误
问题描述
警告错误:无法对未安装的组件执行反应状态更新。
这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 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 {
}
})();
},)
解决方案
您应该在调用 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;
}
}
});
}
推荐阅读
- javascript - Vue - 基于开发或生产模式导入组件
- python - 使用元组在列上应用多个过滤器
- javascript - react-draft-wysiwyg 编辑器文本未显示某些样式
- elasticsearch - 用于嵌套查询的 ElasticSearch 相邻词
- javascript - 撤消 .removeAtribute 函数
- mongodb - 只返回一个对象数组中的一个对象
- linux - 即使在 Amazon Linux 容器中的所需位置有 google-chrome 可执行文件,也缺少 google-chrome
- java - 将 findByNamedQueryAndNamedParam(Srring-ORM 4) 升级到 getNamedQuery(Srping-ORM 5)
- object-detection - 如何使用 swin 变压器 (mmdetection) 分析结果?
- django - 如何创建不同的标签,这是 django wagtail 中的博客所独有的