嗨,当我将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);
}, [dispatch, 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();
}, [dispatch, fetchingFavJokes]);
//Favs
const fetchingFavJokes = useCallback(async () => {
setError(null);
try {
await dispatch(jokeAction.loadFavJokes());
} catch (err) {
setError(err.message);
}
setIsFetchingFav(false);
}, [dispatch, 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;