如何解决:在React-Native中无法在未安装的组件警告上调用setState(或forceUpdate)吗?

时间:2019-04-01 19:33:11

标签: javascript react-native react-navigation

主屏幕的React-native项目中,我从 AsyncStorage 获得了一些值。获得此值后,我将其进行比较并决定下一步将在哪个屏幕上显示。 如果 getValue 为空,则将进入 WelcomeScreen ;如果不为空,则将进入 HomeDrawer 屏幕。

这里我提供了代码-

import React from 'react';
import { StyleSheet, Text, View, AsyncStorage } from 'react-native';
import {StackNavigator} from 'react-navigation';
import WelcomeScreen from './WelcomeScreen';
import LoginScreen from './components/LoginScreen';
import NoteMeHome from './components/NoteMeHome';
import HomeDrawer from './HomeDrawer/HomeDrawer';
import SettingsScreen from './components/SettingsScreen';

class HomeScreen extends React.Component {

  state = {
    getValue: '',

  }

  async componentDidMount() {

    const token = await AsyncStorage.getItem('toke');
    this.setState({ getValue: token });

  }

  render() {
    console.log('#ZZZ:', this.state.getValue);

    if(this.state.getValue !== null) {
      return (
        <AppStackNavigator/>
      );
    } else {
      return (
        <AppStackNavigator2/>
      );
    }

  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});


const AppStackNavigator = new StackNavigator({
  HomeDrawer: {screen:HomeDrawer},
  WelcomeScreen: {screen:WelcomeScreen},


  LoginScreen: {screen:LoginScreen},
  NoteMeHome: {screen:NoteMeHome},

  SettingsScreen: {screen:SettingsScreen}

})

const AppStackNavigator2 = new StackNavigator({
  WelcomeScreen: {screen:WelcomeScreen},
  HomeDrawer: {screen:HomeDrawer},

  LoginScreen: {screen:LoginScreen},
  NoteMeHome: {screen:NoteMeHome},

  SettingsScreen: {screen:SettingsScreen}

})

export default HomeScreen;

现在,运行此命令后,如果我在变量getValue中获得空值,则显示以下警告-

  

警告:无法在已卸载的设备上调用setState(或forceUpdate)   零件。这是空操作,但表示您的内存泄漏   应用。要修复,请取消所有订阅和异步任务   componentWillUnmount方法。

那么,我该如何解决这个警告问题?

2 个答案:

答案 0 :(得分:1)

我不知道这是否是一个好习惯。问题是-我的组件正在使用空字符串初始化,并且我正在检查render函数中的null。使用null初始化getvalue或在render中检查空字符串将解决此问题。

因此,我在代码中所做的更改是-

state = {
    getValue: ''

  }

它消除了警告。

答案 1 :(得分:0)

一个更好的解决方案是使用SwitchNavigator中的react-navigation,因为您的导航堆栈是相同的,并且您只想基于该令牌路由到第一个屏幕。

see example

import React from 'react';
import { StyleSheet, Text, View, AsyncStorage } from 'react-native';
import {StackNavigator, createSwitchNavigator} from 'react-navigation';
import WelcomeScreen from './WelcomeScreen';
import LoginScreen from './components/LoginScreen';
import NoteMeHome from './components/NoteMeHome';
import HomeDrawer from './HomeDrawer/HomeDrawer';
import SettingsScreen from './components/SettingsScreen';

const AppStackNavigator = new StackNavigator({
  HomeDrawer: {screen:HomeDrawer},
  LoginScreen: {screen:LoginScreen},
  NoteMeHome: {screen:NoteMeHome},
  SettingsScreen: {screen:SettingsScreen}
});

export default createAppContainer(createSwitchNavigator(
  {
    LaunchScreen,
    WelcomeScreen,
    AppStackNavigator,
  },
  {
    initialRouteName: 'LaunchScreen',
  }
));

class LaunchScreen extends React.Component {
  constructor(props) {
    super(props);
    this._getToken();
  }

  // Fetch the token from storage then navigate to the appropriate place
  _getToken = async () => {
    const tok = await AsyncStorage.getItem('toke');

    // This will switch to the Welcome screen or main AppStack. Then this launch
    // screen will be unmounted and thrown away.
    this.props.navigation.navigate(tok ? 'AppStackNavigator' : 'WelcomeScreen');
  };

  // Render any loading content that you like here
  render() {
    return (
      <View>
        {/*...*/}
      </View>
    );
  }
}