【问题标题】:Use nested navigators with react-navigation and redux integration使用带有 react-navigation 和 redux 集成的嵌套导航器
【发布时间】:2018-04-08 20:33:41
【问题描述】:

我正在尝试使用带有 redux 集成的嵌套导航器,但应用程序无法加载并出现以下错误:

在我为登录流程添加第二层导航器之前,一切正常。

我怎样才能做到这一点?

这里是导航器的完整代码并将其与 redux 集成:

import React, { Component } from 'react';
import { BackHandler } from "react-native";

import { connect } from 'react-redux';
import { fromJS } from 'immutable';

import { dogTypes } from '../ducks/dog';

import { StackNavigator, addNavigationHelpers, NavigationActions } from 'react-navigation';
import { createReduxBoundAddListener, createReactNavigationReduxMiddleware } from 'react-navigation-redux-helpers';

import MainScreen from '../screens/MainScreen';
import SecondScreen from '../screens/SecondScreen';
import AuthLoadingScreen from '../screens/AuthLoadingScreen';
import AuthScreen from '../screens/AuthScreen';

import HeaderWithMenu from '../components/Headers/HeaderWithMenu';
import HeaderWithBack from '../components/Headers/HeaderWithBack';

import Translations from '../translations/screens';

const MainNavigator = StackNavigator({
  LoginFlow: {
    screen: StackNavigator({
      AuthLoading: AuthLoadingScreen,
      Auth: AuthScreen,
    },
    {
      initialRouteName: 'AuthLoading',
    })
  },
  MainFlow: {
    screen: StackNavigator({
      Main: {
        screen: MainScreen,
        navigationOptions: ({navigation}) => ({
          header: <HeaderWithMenu title={Translations.t('mainScreen')}/>
        })
      },
      Second: { 
        screen: SecondScreen,
        navigationOptions: ({navigation}) => ({
          header: <HeaderWithBack title={Translations.t('secondScreen')} navigation={navigation}/>
        })
      },
    },
    {
      initialRouteName: 'Main'
    })
  }
},
{
  initialRouteName: 'MainFlow'
});

const initialState = fromJS(
  {
    index: 0,
    routes: [
      {
        index: 0,
        key: 'MainFlow',
        routeName: 'MainFlow',
        routes: [
          {
            key: 'Main',
            routeName: 'Main'
          }
        ]
      }
    ]
  }
);

export const mainNavReducer = (state = initialState, action) => {
  let nextState;
  switch (action.type) {
    case dogTypes.DOG_BIGGER:
      nextState = state.merge(MainNavigator.router.getStateForAction(
        MainNavigator.router.getActionForPathAndParams('Second'),
        state.toJS()
      ));
      break;
    default:
      nextState = state.merge(MainNavigator.router.getStateForAction(action, state.toJS()));
      break;
  }

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

export const mainNavMiddleware = createReactNavigationReduxMiddleware(
  "root",
  state => state.nav,
)

const addListener = createReduxBoundAddListener("root");

class App extends Component {
  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
  }
  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
  }
  onBackPress = () => {
    const { dispatch, nav } = this.props;
    if (nav.index === 0) {
      return false;
    }
    dispatch(NavigationActions.back());
    return true;
  };

  render() {
    return (
      <MainNavigator navigation={addNavigationHelpers({
        dispatch: this.props.dispatch,
        state: this.props.nav,
        addListener,
      })} />
    );
  }
}

const mapStateToProps = (state) => {
  return {
    nav: state.get('nav').toJS()
  }
};

export const MainNavigatorComponent = connect(mapStateToProps)(App);

【问题讨论】:

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


    【解决方案1】:

    问题实际上是直接在 react-navigation 库中。我将我的版本更新到了最新版本(此时为 2.0.0-rc.1),它解决了这个问题。

    我仍然喜欢@NewToCoding 定义他的导航器的方式,并且不得不稍微改变一下initialState。这是最终的工作代码:

    const LoginFlow = StackNavigator({
      Auth: AuthScreen,
    },
    {
      initialRouteName: 'Auth',
    });
    
    const MainFlow = StackNavigator({
      Main: {
        screen: MainScreen,
        navigationOptions: ({navigation}) => ({
          header: <HeaderWithMenu title={Translations.t('mainScreen')}/>
        })
      },
      Second: { 
        screen: SecondScreen,
        navigationOptions: ({navigation}) => ({
          header: <HeaderWithBack title={Translations.t('secondScreen')} navigation={navigation}/>
        })
      },
    },
    {
      initialRouteName: 'Main'
    });
    
    const MainNavigator = SwitchNavigator({
      AuthLoading: AuthLoadingScreen,
      App: MainFlow,
      Auth: LoginFlow,
    },
    {
      initialRouteName: 'AuthLoading'
    });
    
    const initialState = fromJS(MainNavigator.router.getStateForAction(NavigationActions.navigate({ routeName: 'AuthLoading' })));
    
    export const mainNavReducer = (state = initialState, action) => {
      let nextState;
      switch (action.type) {
        case dogTypes.DOG_BIGGER:
          nextState = state.merge(MainNavigator.router.getStateForAction(
            NavigationActions.navigate({ routeName: 'Second' }),
            state.toJS()
          ));
          break;
        default:
          nextState = state.merge(MainNavigator.router.getStateForAction(action, state.toJS()));
          break;
      }
    
      // Simply return the original `state` if `nextState` is null or undefined.
      return nextState || state;
    };
    

    【讨论】:

      【解决方案2】:

      StackNavigator 应该自己定义,每个 StackNavigator 都需要在定义其嵌套位置之前定义。

      所以我会怎么做:

      const LoginFlow = StackNavigator({})
      
      const MainFlow = StackNavigator({})
      
      const MainNavigator = StackNavigator({
        Login: {
          screen: LoginFlow //screen is the stack navigator defined above
        },
        Main: {
          screen: MainFlow //screen is the stack navigator defined above
        }
      

      })

      此外,您的初始状态是正确的,请阅读docs,您可以按照他们设置减速器/存储并与 redux 集成的方式复制粘贴。

      【讨论】:

      【解决方案3】:

      这是 React Navigation 的问题。我刚刚更改了 package.json 上的 React Navigation 版本。我花了很多时间来解决它这样做: 而不是这个

      "react-navigation": "^2.18.2",
      "react-navigation-redux-helpers": "^2.0.9",
      

      我改成这个了

      "react-navigation": "2.18.2",
      "react-navigation-redux-helpers": "^2.0.9",
      

      【讨论】:

        猜你喜欢
        • 2019-07-28
        • 1970-01-01
        • 2021-12-17
        • 2022-06-25
        • 2018-07-31
        • 1970-01-01
        • 2018-04-08
        • 2021-03-19
        • 2017-10-12
        相关资源
        最近更新 更多