如何解决useEffect:无法在已卸载的组件上执行React状态更新这是空操作,但表示您的应用程序中发生内存泄漏
嗨,当我将APK版本从28更新为29时,我的react native expo应用程序出现问题-谷歌播放了新的更新。
在依赖关系更新后,在以下错误日志中指定的组件中出现了我的错误:
Warning: Can't perform a React state update on an unmounted component. This is a no-op,but it indicates a memory leak in your application. To fix,cancel all subscriptions and asynchronous tasks in %s.%s,a useEffect cleanup function
我不确定问题出在什么地方
具有useEffect清除尝试的代码:
//React Deps
import React,{ useState,useEffect,useCallback } from "react";
import {
View,StyleSheet,Image,Text,Platform,Button,ActivityIndicator,} from "react-native";
import { SearchBar } from "react-native-elements";
import { HeaderButtons,Item } from "react-navigation-header-buttons";
import { useSelector,useDispatch } from "react-redux";
//Components
import HeaderButton from "../components/HeaderButton";
import JokesList from "../components/JokesList";
//Misc
import Colors from "../constants/Colors";
//Store
import * as jokeAction from "../store/actions/jokes-action";
const HomeScreen = (props) => {
const jokes = useSelector((state) => state.jokes.jokes);
const [search,setIsSearch] = useState(""); //Search
const [newSearch,setIsNewSearch] = useState([]); //New Search
const [isFetching,setIsFetchingFav] = useState(false); //Fav
const [isLoading,setIsLoading] = useState(); //Loading
const [isRefreshing,setIsRefreshing] = useState(false); //Refreshing
const [error,setError] = useState(""); //Errors
const dispatch = useDispatch();
//Load Jokes
useEffect(() => {
let isCancelled = false; //attempt
console.log("load jokes");
setIsLoading(true);
loadJokes().then(() => {
if (!isCancelled) {
setIsLoading(false);
console.log("set is loading to false");
}
});
//Cleanup ?
return () => {
isCancelled = true;
};
},[dispatch,loadJokes]); //Deps
//Loading All Jokes
const loadJokes = useCallback(async () => {
console.log("enter load jokes func");
setError(null);
setIsRefreshing(true);
try {
await dispatch(jokeAction.fetchJokes());
} catch (err) {
setError(err.message);
console.log("error");
}
setIsRefreshing(false);
},setIsLoading,setError]);
//Update after render
useEffect(() => {
console.log("update after render");
const willFocusSub = props.navigation.addListener("willFocus",loadJokes);
return () => {
willFocusSub.remove();
};
},[loadJokes]);
//Load Fav Jokes
useEffect(() => {
console.log("load fav jokes");
fetchingFavJokes();
},fetchingFavJokes]);
//Favs
const fetchingFavJokes = useCallback(async () => {
setError(null);
try {
await dispatch(jokeAction.loadFavJokes());
} catch (err) {
setError(err.message);
}
setIsFetchingFav(false);
},setIsFetchingFav,setError]);
//Events
const updateSearch = (text) => {
setIsSearch(text.toUpperCase());
const newData = jokes.filter((joke) => {
/* When no search text present,do not apply filtering */
if (!text) {
return true;
}
return (
typeof joke.title.toUpperCase() === "string" &&
joke.title.toUpperCase().includes(text.toUpperCase())
);
});
setIsNewSearch(newData);
};
//Loading Spinner
if (isLoading) {
return (
<View style={{ ...styles.screen,...styles.centered }}>
<ActivityIndicator size="large" color="white" />
</View>
);
}
//Error
if (error) {
return (
<View style={{ ...styles.screen,...styles.centered }}>
<Text style={{ color: "white" }}>An Error Occurred!</Text>
<Button
title="Try Again"
onPress={loadJokes}
color={Colors.accentColor}
/>
</View>
);
}
//Fall Back Text
if (!isLoading && jokes.length === 0) {
return (
<View style={styles.centered}>
<Text>No Jokes Found</Text>
</View>
);
}
return (
//Logo
<View style={styles.screen}>
<View style={styles.logoContainer}>
<Image style={styles.logo} source={require("../assets/logo.png")} />
</View>
<View style={styles.searchBar}>
<SearchBar
containerStyle={{
backgroundColor: "white",borderTopColor: "white",borderBottomColor: "white",height: 50,alignItems: "center",justifyContent: "center",}}
inputContainerStyle={{ backgroundColor: "white",height: 40 }}
inputStyle={{
backgroundColor: "white",color: "#232323",fontSize: 16,fontFamily: "luckiest-guy",}}
lightTheme
leftIconContainerStyle={{ backgroundColor: "white" }}
searchIcon={{ size: 24 }}
onChangeText={(text) => {
updateSearch(text);
}}
onClear={(text) => setIsSearch("")}
placeholder="Keyword or Topic..."
value={search}
/>
</View>
<JokesList
listData={!search ? jokes : newSearch}
onRefreshing={loadJokes}
isRefreshing={isRefreshing}
navigation={props.navigation}
/>
</View>
);
};
...Navigation/Styles etc
export default HomeScreen;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。