React Native:nextState.routes.forEach undefined不是对象

时间:2018-01-15 17:24:26

标签: react-native redux react-navigation

我正在使用React Native构建移动应用程序,我遇到的一个问题是导航。现在我正在尝试使用主屏幕实现登录屏幕,我可以从该屏幕注销或调用其他屏幕。为此,由于我使用了redux,我尝试调整StackNavigator,并为它制作一个减速器和一个单独的Component。但在我完成此操作后,我遇到了这个错误:

undefined is not an object (evaluating nextState.routes.forEach)

我的代码在App.js的连接函数中触发了这个错误,该函数必须将一些状态变量映射到导航组件。这是我的代码:

NavReducer.js

import { NavigationActions, StackNavigator } from "react-navigation";
import routes from "../core/routes";


export const AppNavigator = StackNavigator(routes)
const routerForLogin = AppNavigator.router.getActionForPathAndParams('Login')
const routerForPlane = AppNavigator.router.getActionForPathAndParams('PlaneList')
const loginState = AppNavigator.router.getStateForAction(routerForLogin);
const registerState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams('Register'));
const planeListState = AppNavigator.router.getStateForAction(routerForPlane);
const insertState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams('Insert'));

export const navReducer = (state = { loginState, planeListState, insertState, registerState }, action) => {
  switch (action.type) {
    case '@@redux/INIT':
      return {
        ...state,
        planeListState: AppNavigator.router.getStateForAction(routerForPlane, loginState)
      };

    case 'LOGIN':
      return {
        ...state,
        planeListState: AppNavigator.router.getStateForAction(routerForPlane, loginState)
      };

    case 'LOGOUT':
      return {
        ...state,
        loginState: AppNavigator.router.getStateForAction(
          NavigationActions.reset({
            index: 0,
            actions: [NavigationActions.navigate({ routeName: 'Login' })]
          })
        )
      };

    case 'REGISTER':
      return {
        ...state,
        registerState: AppNavigator.router.getStateForAction(action, state.registerState)
      };

    case 'INSERT':
      return {
        ...state,
        insertState: AppNavigator.router.getStateForAction(action, state.insertState)
      };

    default:
      return {
        ...state,
        planeListState: AppNavigator.router.getStateForAction(action, state.planeListState)
      };
  }
};

App.js

import React, { Component } from 'react';
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import thunk from 'redux-thunk';
import { Provider, connect } from 'react-redux';
import { addNavigationHelpers } from 'react-navigation';
import authReducer from './src/reducers/LoginReducer';
import registerReducer from './src/reducers/RegisterReducer';
import planeReducer from './src/reducers/PlaneListReducer';
import insertReducer from './src/reducers/InsertReducer';
import Expo from 'expo';
import { AsyncStorage } from 'react-native'
import { navReducer,AppNavigator } from './src/reducers/NavReducer';

class App extends Component {
  render() {
    const { nav, dispatch } = this.props;

    const state = AsyncStorage.getItem('token')
      ? this.props.nav.planeListState
      : this.props.nav.loginState;

    return (
      <AppNavigator
        screenProps={{ store: { store } }}
        navigation={addNavigationHelpers({
          dispatch: this.props.dispatch,
          state: this.props.nav
        })}
      />
    );
  }
}

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

const AppWithNavigationState = connect(mapStateToProps)(App);

const initialState = {
  auth: { isLoading: false, error: null, username: '', password: '' },
  insert: { wasInserted: false }
};

const rootReducer = combineReducers
  (
  {
    nav: navReducer, auth: authReducer, register: registerReducer, planeList: planeReducer, insert: insertReducer
  }
  );

let store = createStore(rootReducer, initialState, applyMiddleware(thunk));

export default function Root() {
  return (
    <Provider store={store}>
      <AppWithNavigationState />
    </Provider>
  );
}

Routes.js

import LoginComponent from "../components/Login";
import RegisterComponent from "../components/Register";
import PlaneListComponent from "../components/PlaneList";
import InsertComponent from "../components/Insert";

const Routes = {
    Login: { screen: LoginComponent },
    Register: { screen: RegisterComponent },
    PlaneList: { screen: PlaneListComponent },
    Insert: { screen: InsertComponent }
};

export default Routes;

我的代码有什么问题导致该错误?谢谢。

2 个答案:

答案 0 :(得分:1)

根据您的代码,我认为问题是您的 navReducer

我建议您将navReducer名称更改为另一个并将其组合并创建新的Reducer名称navReducer,如下所示。

const navReducer = (state, action) => {
  const newState = AppNavigator.router.getStateForAction(action, state);

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

我还在Github上的我的Repository上推送了react-native-redux-example https://github.com/chen2584/react-native-redux-example

希望这有帮助!

答案 1 :(得分:1)

刚刚通过相同的错误消息:

render的{​​{1}}方法中,您可以定义

App

但是const state = AsyncStorage.getItem('token') ? this.props.nav.planeListState : this.props.nav.loginState; 内的addNavigationHelpers道具正在传递参数AppNavigator

我的猜测是你打算传入你之前定义的state: this.props.nav(你当前没有使用)。试试这个:

state