警告:无法对已卸载的组件执行React状态更新。这是一个无操作,但它指示应用程序中存在内存泄漏。若要修复,请取消useEffect清理函数中的所有订阅和异步任务。
const getData = async () => {
const jsonValue = await AsyncStorage.getItem("@user-info");
if(jsonValue != null) {
setUser(JSON.parse(jsonValue))
} else {
setUser(null)
}
};
useEffect(() => {
getData();
}, []);
```[enter image description here][1][enter image description here][2]
[1]: https://i.stack.imgur.com/y2aSC.png
[2]: https://i.stack.imgur.com/I3zMY.png
编辑,代码登录:下面是发现错误的文件的完整代码。
错误返回为:警告:无法对已卸载的组件执行React状态更新。这是一个无操作,但它指示应用程序中存在内存泄漏。若要修复,请取消useEffect清理函数中的所有订阅和异步任务。
以及:错误:渲染了比上一次渲染更多的挂接。
此错误位于:在性能文件中(在场景视图中.tsx:122)
import React, { useEffect, useState } from "react";
import {
View,
Image,
Text,
TouchableOpacity,
StyleSheet,
SafeAreaView,
Platform,
} from "react-native";
import { icons, images } from "../constants";
import { useFonts } from "expo-font";
import { theme } from "../styles/theme";
import AsyncStorage from "@react-native-async-storage/async-
storage";
export const Perfil = () => {
const [user, setUser] = useState<any>();
const [loaded] = useFonts({
Inter: require("../../assets/fonts/Inter-Bold.ttf"),
InterRegular: require("../../assets/fonts/Inter-Regular.ttf"),
});
if (!loaded) {
return null;
}
useEffect(() => {
let mounted = true;
const getData = async () => {
const jsonValue = await AsyncStorage.getItem("@user-info");
if (mounted === true) {
if(jsonValue != null) {
setUser(JSON.parse(jsonValue))
} else {
setUser(null)
}
}
};
getData();
return () => {
mounted = false;
}
}, []);
function renderHeaderSection() {
return (
<View style={styles.header}>
{/* Image */}
<Image source={images.UserProfileImg} style={styles.userImg} />
{/* User Name */}
<Text style={styles.userName}>{user?.user?.givenName} {user?.user?.familyName}</Text>
{/* Email */}
<Text style={styles.userEmail}>{user?.user?.email}</Text>
{/* Button Edit Profile */}
<TouchableOpacity style={styles.buttonProfile}>
<Text style={styles.textButtonProfile}>Editar Perfil</Text>
<Image
source={icons.ArrowRightImg}
style={{ tintColor: theme.colors.white, width: 8, height: 14 }}
/>
</TouchableOpacity>
</View>
);
}
function renderPreferencesSection() {
return (
<View>
{/* Preferences */}
<View style={styles.preferences}>
<Text style={styles.textPrefences}>Preferences</Text>
</View>
</View>
)
}
return (
<SafeAreaView style={styles.container}>
{renderHeaderSection()}
{renderPreferencesSection()}
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.colors.white,
paddingTop: Platform.OS === "android" ? 50 : 0,
alignItems: 'center'
},
header: {
alignItems: "center",
justifyContent: "center",
},
userImg: {
width: 70,
height: 70,
borderRadius: 100,
},
userName: {
fontSize: 18,
color: theme.colors.black,
paddingVertical: 6,
fontFamily: "Inter",
},
userEmail: {
fontSize: 14,
color: theme.colors.black,
fontFamily: "InterRegular",
},
buttonProfile: {
marginTop: 20,
height: 40,
backgroundColor: theme.colors.primary,
alignItems: "center",
justifyContent: "center",
borderRadius: 20,
paddingHorizontal: 20,
flexDirection: "row",
},
textButtonProfile: {
color: theme.colors.white,
fontFamily: "InterRegular",
fontSize: 14,
paddingRight: 14,
},
preferences: {
minWidth: '90%',
height: 40,
backgroundColor: '#F6F6F6',
borderRadius: theme.border.radius,
marginTop: 30,
justifyContent: 'center',
paddingLeft: 20
},
textPrefences: {
fontSize: 14,
color: theme.colors.gray4
}
});
2条答案
按热度按时间qyswt5oh1#
useEffect
可能会在卸载组件时尝试更新组件的状态,这就是为什么您会收到警告。例如,
getData
被useEffect
调用,在它等待的时候,组件可能会被卸载,所以如果你的异步AsyncStorage.getItem
调用在组件被卸载后解决,它会尝试在一个不再被装载的组件上调用setUser
。如果
setUser
已挂载,您只能调用它:在这个模式中,本地变量
mounted
保护setUser
不被调用,如果它是false
,我们可以通过包含一个cleanup函数作为useEffect
的返回值来确保在组件卸载时将其设置为false。hfwmuf9z2#
这里的问题可能与
useFonts
有关;如果你看一下the code,你会发现它在一个异步调用之后调用了一个状态修饰符:
这足以导致所讨论的错误。
你能做的最好的事情就是忽略这个警告,编写你自己版本的钩子,或者使用像
patch-package
这样的模块来修补它的行为。