首页 > 解决方案 > TypeError:未定义不是对象(评估“navigation.state”)

问题描述

这是我的 AppNavigation.js

 import React from "react";
import { Animated, Easing, Image, StyleSheet, Alert } from "react-native";
import { connect } from "react-redux";
import {
  createReactNavigationReduxMiddleware,
  reduxifyNavigator
} from "react-navigation-redux-helpers";
import { createDrawerNavigator  } from 'react-navigation-drawer'; 
import HomeScreen from "../screens/HomeScreen";
import LogoutScreen from "../screens/LogoutScreen";
import LoginScreen from "../screens/LoginScreen";
import SignupScreen from "../screens/SignupScreen";
import WelcomeScreen from "../screens/WelcomeScreen";
import { AppIcon, AppStyles } from "../AppStyles";
import { Configuration } from "../Configuration";
import DrawerContainer from "../components/DrawerContainer";
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs'

const noTransitionConfig = () => ({
  transitionSpec: {
    duration: 0,
    timing: Animated.timing,
    easing: Easing.step0
  }
});

const middleware = createReactNavigationReduxMiddleware(
  "root",
  state => state.nav
);

// login stack
const LoginStack = createStackNavigator(
  {
    Login: { screen: LoginScreen },
    Signup: { screen: SignupScreen },
    Welcome: { screen: WelcomeScreen }
  },
  {
    initialRouteName: "Welcome",
    headerMode: "float",
    navigationOptions: ({ navigation }) => ({
      headerTintColor: "red",
      headerTitleStyle: styles.headerTitleStyle
    }),
    cardStyle: { backgroundColor: "#FFFFFF" }
  }
);

const HomeStack = createStackNavigator(
  {
    Home: { screen: HomeScreen }
  },
  {
    initialRouteName: "Home",
    headerMode: "float",

    defaultNavigationOptions: {
        title: 'Centered',
        headerTitleAlign: "center"
    },
    navigationOptions: ({ navigation }) => ({
      headerTintColor: "blue",
      headerTitleStyle: styles.headerTitleStyle
    }),
    cardStyle: { backgroundColor: "#FFFFFF" }
  }
);

const LogoutStack = createStackNavigator(
  {
    Logout: { screen: LogoutScreen }
  },
  {}
);

const TabNavigator = createBottomTabNavigator(
  {
    Home: { screen: HomeStack },
    Logout: {
      screen: LogoutStack,   // Empty screen, useless in this specific case
      navigationOptions: ({navigation}) => ({
            tabBarOnPress: (scene, jumpToIndex) => {
                return Alert.alert(   // Shows up the alert without redirecting anywhere
                    'Confirmation required',
                    'Do you really want to logout?',
                    [
                      {text: 'Accept', onPress: () => { navigation.dispatch({ type: 'Logout' }) }},
                      {text: 'Cancel'}
                    ]
                );
            },
        })
     },
  },
  {
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, tintColor }) => { 
        const { routeName } = navigation.state;
        let iconName;
        if (routeName === "Home") {
          iconName = AppIcon.images.home;
        }
        if (routeName === "Logout") {
          iconName = AppIcon.images.logout;
        }
        // You can return any component that you like here! We usually use an
        // icon component from react-native-vector-icons
        return (
          <Image
            style={{
              tintColor: focused ? AppStyles.color.tint : AppStyles.color.grey, 
              width: 25,
              height: 25,
              resizeMode: 'stretch',
            }}
            source={iconName}
          />
        );
      }
    }),
    initialLayout: {
      height: 300
    },
    tabBarOptions: {
      showIcon: true,
      showLabel: true,
      activeTintColor: AppStyles.color.tint,
      inactiveTintColor: "gray",
      style: {
        height: Configuration.home.tab_bar_height
      }
    }
  }
);

// drawer stack
const DrawerStack = createDrawerNavigator (
  {
    Tab: TabNavigator
  },
  {
    drawerPosition: "left",
    initialRouteName: "Tab",
    drawerWidth: 200,
    contentComponent: DrawerContainer
  }
);

// Manifest of possible screens
const RootNavigator = createStackNavigator(
  {
    LoginStack: { screen: LoginStack },
    DrawerStack: { screen: DrawerStack }
  },
  {
    // Default config for all screens
    headerMode: "none",
    initialRouteName: "DrawerStack",
    transitionConfig: noTransitionConfig,
    navigationOptions: ({ navigation }) => ({
      color: "black"
    })
  }
);

const AppWithNavigationState = reduxifyNavigator(RootNavigator, "root");

const mapStateToProps = state => ({
  state: state.nav
});

const AppNavigator = connect(mapStateToProps)(AppWithNavigationState);

const styles = StyleSheet.create({
  headerTitleStyle: {
    fontWeight: "bold",
    textAlign: "center",
    alignSelf: "center",
    color: "black",
    flex: 1,
    fontFamily: AppStyles.fontName.main
  }
});

export { RootNavigator, AppNavigator, middleware };

这是 LogoutScreen.js

import React from "react";
import {
    View,
} from "react-native";
import { connect } from "react-redux";
import { withNavigation } from 'react-navigation';

class LogoutScreen extends React.Component {
    static navigationOptions = ({ navigation }) => ({
        title: "Logout"
    });

    constructor(props) {
        super(props);
    }

    render() {
        return (
            <View>
            
            </View>
        );
    }

}

const mapStateToProps = state => ({});

export default withNavigation(LogoutScreen);

这是 index.js

import { NavigationActions } from "react-navigation";
import { combineReducers } from "redux";
import { RootNavigator } from "../navigations/AppNavigation";
import firebase from "react-native-firebase";
import AsyncStorage from '@react-native-async-storage/async-storage';

// Start with two routes: The Main screen, with the Login screen on top.
const firstAction = RootNavigator.router.getActionForPathAndParams(
  "LoginStack"
);
const initialNavState = RootNavigator.router.getStateForAction(firstAction);

function nav(state = initialNavState, action) {
  let nextState;
  switch (action.type) {
    case "Login":
      nextState = RootNavigator.router.getStateForAction(
        NavigationActions.navigate({ routeName: "DrawerStack" }),
        state
      );
      break;
    case "Logout":
      try {
        nextState = RootNavigator.router.getStateForAction(
          NavigationActions.navigate({ routeName: "LoginStack" }),
          state
        );
      } catch (e) {
        console.log(e);
      }
      break;
    default:
      nextState = RootNavigator.router.getStateForAction(action, state);
      break;
  }

  // Simply return the original `state` if `nextState` is null or undefined.
  return nextState || state;
}

const initialAuthState = { isLoggedIn: false };

function auth(state = initialAuthState, action) {
  switch (action.type) {
    case "Login":
      return { ...state, isLoggedIn: true };
    case "Logout":
      AsyncStorage.removeItem("@accessToken");
      AsyncStorage.removeItem("@refreshToken");
      return { ...state, isLoggedIn: false };
    default:
      return state;
  }
}

const AppReducer = combineReducers({
  nav,
  auth
});

export default AppReducer;

我不知道我做错了什么。当我单击注销选项卡按钮时,我收到“TypeError:未定义不是对象(评估'navigation.state')”,查看const TabNavigator = createBottomTabNavigator.

我尝试了到目前为止我能找到的一切,但仍然没有运气。我想完成进一步的行为:当有人单击选项卡栏中的注销按钮以注销并重定向到登录屏幕时。

标签: javascriptreactjsreact-nativereact-navigation

解决方案


推荐阅读