反应本机内存泄漏反应导航

时间:2021-04-22 06:15:09

标签: react-native expo react-navigation

我想检查用户是否在 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'
      }}} />

 .....

getSecureToken:

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;

1 个答案:

答案 0 :(得分:0)

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

首先,从 here

安装 expo-app-loading

然后,在您的 navigation 所在的位置创建一个名为 App.js 的文件夹。然后在其中创建一个名为 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>
  );
}