反应本机导航-componentDidMount()被触发两次

时间:2018-09-18 08:33:26

标签: react-native react-redux react-native-android react-native-navigation

我是React Native的新手。我正在尝试构建一个具有Splash屏幕的应用程序,如果用户未通过身份验证,该屏幕随后将导航到Login屏幕;如果用户已通过身份验证,则将导航至Main屏幕。使用this.props.navigation.navigate()完成此操作 问题是Splash组件将被安装两次。我通过在componentDidMount()的{​​{1}}内打印来进行检查。因此,登录/主屏幕进入两次,看起来非常不愉快。有没有什么办法解决这一问题? 另外,当屏幕使用SplashSplash变为LoginMain时,我想添加一些延迟。无论如何要这样做吗? 这是我的代码:

index.js

setTimeout()

Splash.js

import React from 'react';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import reduxThunk from 'redux-thunk';
import reducers from './src/reducers';

import { StyleSheet } from 'react-native';
import LoginScreen from './src/components/Login/LoginScreen';
import Splash from './src/components/Login/Splash';
import Navigation from './src/components/Navigation/Navigation';
import { Font } from 'expo';
import {
  createStackNavigator
} from 'react-navigation';

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
const store = createStoreWithMiddleware(reducers);
const persistor = persistStore(store);

export default class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      fontLoaded: false,
      currentScreen: 'Splash',
    };
    setTimeout(() => this.setState({currentScreen: 'Login'}), 2000);
  }

  async componentDidMount() {
    await Font.loadAsync({
      'Quicksand': require('./assets/fonts/Quicksand-Regular.ttf'),
      'Quicksand-Medium': require('./assets/fonts/Quicksand-Medium.ttf'),
      'Quicksand-Bold': require('./assets/fonts/Quicksand-Bold.ttf'),
    });
    this.setState({ fontLoaded: true });
  }

  render() {
    const MainNavigator = createStackNavigator({
      Splash: { screen: Splash },
      Main: { screen: Navigation },
      Login: { screen: LoginScreen },
    })
    if (this.state.fontLoaded)
      return (
        <Provider store={store}>
          <MainNavigator></MainNavigator>
        </Provider>
      )
    else return null;
  }
}

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

1 个答案:

答案 0 :(得分:2)

Solution

Take out the createStackNavigator from render. It is better way wrapping screens above App class.

const MainNavigator = createStackNavigator({
  Splash: { screen: Splash },
  Main: { screen: Navigation },
  Login: { screen: LoginScreen },
})

export default class App extends React.Component {
...

Why?

render is run repeatedly depends on various conditions as changing state, props and so on.
And your code looks making multiple components with createStackNavigation in render. Take out :)

p.s If you want to wait loading fonts before show home screen, just change to home screen from splash screen after loaded fonts. Thus, the better way is loading fonts in SplashScreen and do what you want.