【问题标题】:react native memory leak react navigation反应本机内存泄漏反应导航
【发布时间】:2021-04-22 06:15:09
【问题描述】:

我想检查用户是否在 useEffect 中有安全令牌,但我收到此错误消息。

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.

当我使用 useEffect 时会发生这种情况。如果我删除它,则不会收到错误消息,但我需要检查用户是否拥有令牌。

import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import getSecureKey from '../utilies/getSecureKey';

const Stack = createStackNavigator();

const AppStack = ({ navigation }) => {

  useEffect(() => {
    getSecureKey().then(res => console.log(res)).catch(e => console.log(e));
  }, []);

  return (
    <Stack.Navigator showIcon={true} initialRouteName="AppTabs">
      <Stack.Screen name="AppTabs" component={AppTabs} options={{headerTitle: () => <Header />, headerStyle: {
        backgroundColor: '#fff'
      }}} />

 .....

获取安全令牌:

import * as SecureStore from 'expo-secure-store';

const getSecureKey = async () => {
  const key = await SecureStore.getItemAsync('jwt');
  return key;
};

export default getSecureKey;

App.js

import React, { useState, useEffect } from 'react';
import * as Font from 'expo-font';
import { NavigationContainer } from '@react-navigation/native';
import AppLoading from 'expo-app-loading';
import { Provider } from 'react-redux';
import store from './src/redux/store/index';
import AppStack from './src/navigation/stack';

const getFonts = async () => {
  await Font.loadAsync({
    "nunito-regular": require("./assets/fonts/Nunito-Regular.ttf"),
    "nunito-bold": require("./assets/fonts/Nunito-Bold.ttf"),
  });
};

const App = () => {
  const [fontsLoaded, setFontsLoaded] = useState(false);

  if(fontsLoaded) {
  return (
    <Provider store={store}>
      <NavigationContainer><AppStack /></NavigationContainer>
    </Provider>)
  } else {
    return (<AppLoading startAsync={getFonts} onFinish={() => setFontsLoaded(true)} onError={() => {}} />)
  }
};

export default App;

【问题讨论】:

    标签: react-native expo react-navigation


    【解决方案1】:

    不要在导航器中恢复令牌。而是这样做 -

    首先,从here安装expo-app-loading

    然后,在您的App.js 所在的位置创建一个名为navigation 的文件夹。然后在其中创建一个名为 AppNavigator.js 的文件。

    AppNavigator.js内,粘贴这个

    import React, { useEffect } from 'react';
    import { View, Text } from 'react-native';
    import { createStackNavigator } from '@react-navigation/stack';
    import getSecureKey from '../utilities/getSecureKey';
    
    const Stack = createStackNavigator();
    
    const AppNavigator = () => {
      // Remove these Lines --
      // useEffect(() => {
      //   getSecureKey()
      //     .then((res) => console.log(res))
      //     .catch((e) => console.log(e));
      // }, []);
    
      return (
        <Stack.Navigator showIcon={true} initialRouteName="AppTabs">
          <Stack.Screen
            name="AppTabs"
            component={AppTabs}
            options={{
              headerTitle: () => <Header />,
              headerStyle: {
                backgroundColor: '#fff',
              },
            }}
          />
        </Stack.Navigator>
      );
    };
    
    export default AppNavigator;
    

    为您的 fonts 创建一个名为 hooks 的文件夹,您的 App.js 位于该文件夹中,并在其中创建一个文件 useFonts.js

    useFonts.js这样写-

    import * as Font from "expo-font";
    
    export default useFonts = async () => {
      await Font.loadAsync({
        "nunito-regular": require("./assets/fonts/Nunito-Regular.ttf"),
        "nunito-bold": require("./assets/fonts/Nunito-Bold.ttf"),
      });
    };
    

    在你的App.js

    import React, { useState } from 'react';
    import { Text, View, StyleSheet } from 'react-native';
    import Constants from 'expo-constants';
    import { NavigationContainer } from '@react-navigation/native';
    import AppLoading from 'expo-app-loading';
    import useFonts from "./hooks/useFonts";
    
    import getSecureKey from './utilities/getSecureKey';
    import AppNavigator from './navigation/AppNavigator';
    
    export default function App() {
      const [IsReady, SetIsReady] = useState(false);
    
      // Always perform Token Restoration in App.js just to keep code clear.    
      const FontAndTokenRestoration = async () => {
        await useFonts(); // Font is being loaded here
        const token = await getSecureKey();
        if (token) {
          console.log(token);
        }
      };
    
      if (!IsReady) {
        return (
          <AppLoading
            startAsync={FontAndTokenRestoration}
            onFinish={() => SetIsReady(true)}
            onError={() => {}}
          />
        );
      }
    
      return (
        <NavigationContainer>
          <AppNavigator />
        </NavigationContainer>
      );
    }
    

    【讨论】:

    • 非常感谢!但我有一个问题。我已经使用 Apploading 来加载字体。如何加载两个函数?
    • 是的,您也可以使用AppLoading 来做到这一点。告诉我你是如何加载字体的。我可能会告诉你一个更好的方法来做到这一点。在问题中更新它
    • 感谢您的宝贵时间!我更新了上面的 app.js 文件 :)
    • 它的工作原理谢谢!可以吗?如果存在我在那里派发 Api 的令牌?因为我必须加载用户数据。我知道怎么做我只问如果这是一个好方法
    • 是的,完全没问题。
    猜你喜欢
    • 2020-03-05
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2019-08-09
    相关资源
    最近更新 更多