我正在尝试使用带有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);
答案 0 :(得分:0)
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,您可以直接复制粘贴设置Reducer / store并与redux集成的方式。
答案 1 :(得分:0)
这个问题实际上是反应导航库中的直接问题。我将我的版本更新到最新版本(此时为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 :(得分:0)
这是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",