如何使用 React Navigation 5 在 Action Creator 中导航到屏幕
How to Navigate to Screen inside Action Creators with React Navigation 5
在React Navigation 5 Auth Flow中,它说当条件状态改变时屏幕将自动导航。
- 我已将屏幕设置为在
状态下导航至主屏幕
isAuthenticated 更改为 true。
- 控制台没有错误。 isAuthenticated 确实更改为
是的,但是屏幕在 state 之后没有导航到 HomeScreen
改变。
- 我也尝试过使用 {NavigationActions} 和
动作创建者中的 {CommonActions}。强制导航,但是
也不工作。
AuthStackNav.js
import React from 'react';
import { connect } from 'react-redux';
import {createStackNavigator} from '@react-navigation/stack';
import AuthScreen from '../screens/AuthScreen';
import HomeScreen from '../screens/HomeScreen';
const AuthStackNav = ({isAuthenticated}) => {
const AuthStack = createStackNavigator();
return (
<AuthStack.Navigator initialRouteName='Auth'>
{
isAuthenticated ?
<AuthStack.Screen name='Home' component={HomeScreen} />
:
<AuthStack.Screen name='Auth' component={AuthScreen} />
}
</AuthStack.Navigator>
);
};
const mapStateToProps = ({isAuthenticated}) => {
return {isAuthenticated};
};
export default connect(mapStateToProps, null)(AuthStackNav);
userActions.js
import {LOGIN_WITH_FACEBOOK} from './types';
import {NavigationActions} from 'react-navigation';
import { CommonActions } from '@react-navigation/native';
export const loginWithFacebook = () => (dispatch) => {
dispatch({ type: LOGIN_WITH_FACEBOOK, payload: {isAuthenticated: true} });
dispatch(NavigationActions.navigate({routeName:'Home'}));
dispatch( CommonActions.navigate({ name: 'Home' }) );
};
userReducer.js
import {LOGIN_WITH_FACEBOOK} from '../actions/types.js';
const initialState = {
isAuthenticated: false
};
const userReducer = (state=initialState, action) => {
switch(action.type){
case LOGIN_WITH_FACEBOOK:
return {...state, ...action.payload};
default:
return state;
}
}
export default userReducer;
AuthScreen.js
import React from 'react';
import {Text, View, StyleSheet, Image, TouchableOpacity, SafeAreaView} from 'react-native';
import { connect } from 'react-redux';
import {loginWithFacebook} from '../actions/userActions';
const AuthScreen = ({loginWithFacebook}) => {
return (
<View style={styles.screenContainer}>
<TouchableOpacity
activeOpacity={0.5}
onPress={loginWithFacebook}
> Facebook Login</TouchableOpacity>
</View>
);
};
const mapDispatchToProps = {
loginWithFacebook
};
export default connect(null, mapDispatchToProps)(AuthScreen);
AppNav.js
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import AuthStackNav from './AuthStackNav';
const AppNav = () => {
return (
<NavigationContainer>
<AuthStackNav />
</NavigationContainer>
);
};
export default AppNav;
我用这个 guide 解决了这个问题。
RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
AppNav.js
import { navigationRef } from './RootNavigation.js';
const AppNav = () => {
return (
<NavigationContainer ref={navigationRef} >
<AuthStackNav />
</NavigationContainer>
);
};
export default AppNav;
userActions.js
export const loginWithFacebook = () => (dispatch) => {
dispatch({ type: LOGIN_WITH_FACEBOOK, payload: {isAuthenticated: true} });
RootNavigation.navigate('Home');
};
Kaizen Tamashi 的回答是正确的。
此外,如果您想要 goBack 功能,只需在 RootNavigation.js
中添加此代码
export function goBack() {
navigationRef.current?.goBack();
}
在React Navigation 5 Auth Flow中,它说当条件状态改变时屏幕将自动导航。
- 我已将屏幕设置为在
状态下导航至主屏幕 isAuthenticated 更改为 true。 - 控制台没有错误。 isAuthenticated 确实更改为 是的,但是屏幕在 state 之后没有导航到 HomeScreen 改变。
- 我也尝试过使用 {NavigationActions} 和 动作创建者中的 {CommonActions}。强制导航,但是 也不工作。
AuthStackNav.js
import React from 'react';
import { connect } from 'react-redux';
import {createStackNavigator} from '@react-navigation/stack';
import AuthScreen from '../screens/AuthScreen';
import HomeScreen from '../screens/HomeScreen';
const AuthStackNav = ({isAuthenticated}) => {
const AuthStack = createStackNavigator();
return (
<AuthStack.Navigator initialRouteName='Auth'>
{
isAuthenticated ?
<AuthStack.Screen name='Home' component={HomeScreen} />
:
<AuthStack.Screen name='Auth' component={AuthScreen} />
}
</AuthStack.Navigator>
);
};
const mapStateToProps = ({isAuthenticated}) => {
return {isAuthenticated};
};
export default connect(mapStateToProps, null)(AuthStackNav);
userActions.js
import {LOGIN_WITH_FACEBOOK} from './types';
import {NavigationActions} from 'react-navigation';
import { CommonActions } from '@react-navigation/native';
export const loginWithFacebook = () => (dispatch) => {
dispatch({ type: LOGIN_WITH_FACEBOOK, payload: {isAuthenticated: true} });
dispatch(NavigationActions.navigate({routeName:'Home'}));
dispatch( CommonActions.navigate({ name: 'Home' }) );
};
userReducer.js
import {LOGIN_WITH_FACEBOOK} from '../actions/types.js';
const initialState = {
isAuthenticated: false
};
const userReducer = (state=initialState, action) => {
switch(action.type){
case LOGIN_WITH_FACEBOOK:
return {...state, ...action.payload};
default:
return state;
}
}
export default userReducer;
AuthScreen.js
import React from 'react';
import {Text, View, StyleSheet, Image, TouchableOpacity, SafeAreaView} from 'react-native';
import { connect } from 'react-redux';
import {loginWithFacebook} from '../actions/userActions';
const AuthScreen = ({loginWithFacebook}) => {
return (
<View style={styles.screenContainer}>
<TouchableOpacity
activeOpacity={0.5}
onPress={loginWithFacebook}
> Facebook Login</TouchableOpacity>
</View>
);
};
const mapDispatchToProps = {
loginWithFacebook
};
export default connect(null, mapDispatchToProps)(AuthScreen);
AppNav.js
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import AuthStackNav from './AuthStackNav';
const AppNav = () => {
return (
<NavigationContainer>
<AuthStackNav />
</NavigationContainer>
);
};
export default AppNav;
我用这个 guide 解决了这个问题。
RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
AppNav.js
import { navigationRef } from './RootNavigation.js';
const AppNav = () => {
return (
<NavigationContainer ref={navigationRef} >
<AuthStackNav />
</NavigationContainer>
);
};
export default AppNav;
userActions.js
export const loginWithFacebook = () => (dispatch) => {
dispatch({ type: LOGIN_WITH_FACEBOOK, payload: {isAuthenticated: true} });
RootNavigation.navigate('Home');
};
Kaizen Tamashi 的回答是正确的。 此外,如果您想要 goBack 功能,只需在 RootNavigation.js
中添加此代码export function goBack() {
navigationRef.current?.goBack();
}