无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。 在PokemonListItem中(在PokemonList.jsx:148处)
好的,我知道这是一个常见问题,解决方案应该非常简单。我只是不知道如何在我的代码中实现它。
我正在使用React-Native和PokéAPI制作一种用于移动设备的Pokédex。我不确定泄漏在哪里,所以请有经验的开发人员提供帮助。
export default function PokemonListItem({ url, Favorite }) {
const [pokemondata, setData] = React.useState({});
const [dataReady, setReady] = React.useState(false);
const [isFavorite, setFavorite] = React.useState(false);
const favoriteStatus = (bool) => {
setFavorite(bool);
};
const getData = async () => {
await fetch(url)
.then((res) => res.json())
.then((data) => setData(data));
setReady(true);
};
React.useEffect(() => {
getData();
}, []);
more code...
const renderItem = ({ item }) => (
<TouchableHighlight
style={{ borderRadius: 10 }}
underlayColor="#ffc3c2"
onPress={() => {
navigation.navigate("Pokémon Details", {
url: item.url,
});
}}
>
<PokemonListItem url={item.url} Favorite={FavoriteButton} />
</TouchableHighlight>
);
如果需要查看完整的代码,可以访问repository。
答案 0 :(得分:0)
一种方法似乎是维护一个变量,以查看组件是否仍在安装中,这对我来说(React-hooks. Can't perform a React state update on an unmounted component)感觉很不舒服({{3}})-但是无论如何我会在您的代码中看到它...
let isMounted;
const getData = async () => {
await fetch(url)
.then((res) => res.json())
.then((data) => { if(isMounted) setData(data)});
setReady(true);
};
React.useEffect(() => {
isMounted = true;
getData();
return () => {
isMounted = false;
}
}, []);
答案 1 :(得分:0)
尝试一下
React.useEffect(() => {
(async function onMount() {
await fetch(url)
.then((res) => res.json())
.then((data) => setData(data));
setReady(true);
})();
}, []);
答案 2 :(得分:0)
类似于前面提到的,关键是将状态更新<div>
<a class="menu-item">
<div class="icon"></div>
<span>Example</span>
</a>
<a class="menu-item" style="font-variant: all-small-caps">
<div class="icon"></div>
<span>Example</span>
</a>
</div>
包装在setReady()
块中。
if (mounted){}
let mounted = true;
的挂载return () => { mounted = false }
包裹setState调用if (mounted) { setState(...)}
https://codesandbox.io/s/upbeat-easley-kl6fv?file=/src/App.tsx
如果删除useEffect(() => {
let mounted = true;
const apiRequest = async (setReady) => {
let response;
try {
response = await APICall();
if (mounted) {
setReady(response.data);
}
} catch (error) {}
}
apiRequest();
return () => { mounted = false;}
})
调用并刷新,则会发现内存泄漏错误消失了。