[英]How to solve "can't perform a react state update on an unmounted component"
Can't perform a React state update on an unmounted component.
无法对卸载的组件执行 React 状态更新。 This is a no-op, but it indicates a memory leak in your application.
这是一个空操作,但它表明您的应用程序中存在内存泄漏。 To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。 in PokemonListItem (at PokemonList.jsx:148)
在 PokemonListItem 中(在 PokemonList.jsx:148)
Okay so I know this is a common issue and the solution should be quite simple.好的,我知道这是一个常见问题,解决方案应该很简单。 I just don't know how to implement it to my code.
我只是不知道如何在我的代码中实现它。
I'm making a kind of Pokédex for mobile using React-Native and PokéAPI.我正在使用 React-Native 和 PokéAPI 为移动设备制作一种 Pokédex。 I'm not sure where the leak lies, so more experienced developers, please help.
我不确定泄漏在哪里,所以请更有经验的开发人员帮忙。
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>
);
if you need to see the full code, you can visit the repository .如果您需要查看完整代码,可以访问存储库。
An approach seems to be to maintain a variable to see whether or not the component is still mounted or not, which feels smelly to me ( React-hooks. Can't perform a React state update on an unmounted component )- but anyway this is how I would see it in your code...一种方法似乎是维护一个变量以查看组件是否仍然安装,这对我来说感觉很糟糕( React-hooks。无法在未安装的组件上执行 React 状态更新)-但无论如何这是我将如何在您的代码中看到它...
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;
}
}, []);
Try this尝试这个
React.useEffect(() => { (async function onMount() { await fetch(url) .then((res) => res.json()) .then((data) => setData(data)); setReady(true); })(); }, []);
Similar to what was mentioned earlier, the key point being wrapping your state update setReady()
in an if (mounted){}
block .与前面提到的类似,关键点是将状态更新
setReady()
包装在if (mounted){}
块中。
let mounted = true;
let mounted = true;
in your effect that has the async callreturn () => { mounted = false }
return () => { mounted = false }
if (mounted) { setState(...)}
if (mounted) { setState(...)}
包裹 setState 调用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;}
})
https://codesandbox.io/s/upbeat-easley-kl6fv?file=/src/App.tsx https://codesandbox.io/s/upbeat-easley-kl6fv?file=/src/App.tsx
If you remove the || true
如果删除
|| true
|| true
call and refresh you'll see that the error for mem leak is gone. || true
调用和刷新你会看到内存泄漏的错误消失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.