【问题标题】:How to useEffect cleanup function in react native?react native如何使用Effect清理功能?
【发布时间】:2020-10-02 14:15:07
【问题描述】:

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请取消 %s 中的所有订阅和异步任务。%s,一个 useEffect 清理函数,

const Drawer = createDrawerNavigator();

const App = () => {
  const [isLoading, setIsLoading] = React.useState(true);
  const [userToken, setUserToken] = React.useState(null);

  const authContext = React.useMemo(() => ({
    SignIn: () => {
      setUserToken('qwertyuiop');
      setIsLoading(false);
    },
    SignOut: () => {
      setUserToken(null);
      setIsLoading(false);
    },
    SignUp: () => {
      setUserToken('qwe');
      setIsLoading(false);
    },
  }));

  useEffect(() => {
    setTimeout(() => {
      setIsLoading(false);
    }, 1000);
  }, []);

  if (isLoading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator size="large" />
      </View>
    );
  }

  console.log("userToken", userToken)
  console.log("authContext", authContext)
  return (
    <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        {userToken !== null ? (
          <Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
            <Drawer.Screen name="HomeDrawer" component={MainTabScreen} />
            <Drawer.Screen name="Support" component={SupportScreen} />
            <Drawer.Screen name="Setting" component={SettingScreen} />
            <Drawer.Screen name="Bookmark" component={BookmarkScreen} />
          </Drawer.Navigator>
        )
          :
          <RootStackScreen />
        }
      </NavigationContainer>
    </AuthContext.Provider>
  );
}

【问题讨论】:

    标签: reactjs react-native react-redux react-router


    【解决方案1】:

    卸载时应始终清除 setTimeouts setIntervals。

    useEffect(() => {
      const timeout = setTimeout(() => {
        setIsLoading(false);
      }, 1000);
    
      return () => clearTimeout(timeout);
    }, []);
    

    您收到此警告是因为 setTimeout 仍在处理中,即使组件已卸载。

    【讨论】:

      【解决方案2】:

      语法很简单:

      useEffect(() => {
          setTimeout(() => {
            setIsLoading(false);
          }, 1000);
          return () => someCleanUp() // your cleanup function
      }, []);
      

      【讨论】:

        【解决方案3】:

        为了防止组件在卸载时不更新状态,您可以使用useRef 和清理功能

        const mounted = useRef(false);
        
        useEffect(() => {
            mounted.current = true;
        
            setTimeout(() => {
              if (mounted.current) {
                setIsLoading(false);
              }
            }, 1000);
        
            return function cleanup() {
              mounted.current = false;
            }
        }, []);
        

        【讨论】:

          【解决方案4】:

          解决方案

          使用 Axios:

          import axios from 'axios';

          组件:

          const Home: React.FC = () => {
          
          let cancelToken: any = axios.CancelToken;
          let source = cancelToken.source();
          
          useEffect(() => {
              (async () => {
          
                try {
                  const data = await axios.get("https://<you-api-url>", {
                      cancelToken: source.token
                  });
                  
                }catch (error) {
                  if (axios.isCancel(error)) {
                    console.log('Request canceled', error.message);
                  } else {
                    // handle error
                    console.log(error);
                  }
                }
          
              })();
          
              return () => {
                //when the component unmounts
                console.log("component unmounted");
          
                // cancel the request (the message parameter is optional)
                source.cancel('Operation canceled by the user.');
              }
          }, []); //End UseEffect
          
          return ();
          
          };
          
          export default Home;
          

          以上实现是根据原始 Axios 文档,阅读 here 以了解详细信息。

          【讨论】:

            猜你喜欢
            • 2021-10-26
            • 2021-10-31
            • 2021-04-09
            • 2021-05-24
            • 1970-01-01
            • 2017-09-16
            • 2021-02-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多