简体   繁体   English

如何解决“无法对未安装的组件执行反应状态更新”

[英]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.我不确定泄漏在哪里,所以请更有经验的开发人员帮忙。

PokemonListItem口袋妖怪列表项

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...

PokemonList口袋妖怪列表

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){}块中。

  1. Create local variable to represent your initial mounted state let mounted = true;创建局部变量来表示您的初始安装状态let mounted = true; in your effect that has the async call在具有异步调用的效果中
  2. Use the cleanup effect https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect to set mounted to false return () => { mounted = false }使用清理效果https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect设置mounted为false return () => { mounted = false }
  3. Wrap the setState call with 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.

相关问题 如何修复无法在未安装的组件上执行 React state 更新 - How to fix Can't perform a React state update on an unmounted component React - 无法在未安装的组件上执行 React state 更新 - React - Can't perform a React state update on an unmounted component React Can't perform a React state update on an unmounted component error - React Can't perform a React state update on an unmounted component error React Native:无法对未安装的组件执行 React state 更新 - React Native: Can't perform a React state update on an unmounted component React 导致:无法对未安装的组件执行 React state 更新 - React causing: Can't perform a React state update on an unmounted component React:无法在未安装的组件上执行 React state 更新 - React: Can't perform a React state update on an unmounted component 导航问题 - 无法对卸载的组件执行 React 状态更新 - Navigation issue - can't perform a React state update on unmounted component 无法在未安装的组件主题提供程序上执行 React state 更新 - Can't perform a React state update on an unmounted component theme provider 无法使用 useEffect 挂钩对未安装的组件执行 React state 更新 - Can't perform a React state update on an unmounted component with useEffect hook 无法对 setInterval 的未安装组件执行 React state 更新 - Can't perform a React state update on an unmounted component for setInterval
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM