我想从我的reduc动作文件导航。 第一个屏幕是登录,因此点击登录按钮后将调用redux动作创建者,reducer生成一个新状态。因此,在我想要重定向到我的仪表板的操作之后。
我正在使用
反应原生+ redux +反应导航
登录组件文件( LoginCmp.js ):
import React, { Component } from 'react';
import {
Text,
View,
ScrollView,
KeyboardAvoidingView
} from 'react-native';
import { connect } from 'react-redux';
import { fieldChange, LoginAction } from '../../actions';
import { Button, Section, Input, Alert } from '../Helpers';
LoginAction(){
const payload = {
email: this.props.email,
password: this.props.password
};
this.props.LoginAction(payload); // Action call
}
render() {
return (
<KeyboardAvoidingView
style={styles.container}
behavior="padding"
>
<View>
<ScrollView contentContainerStyle={styles.contentContainer}>
<Text style={styles.headerText}> Login </Text>
{this.alertMessage()}
<Section>
<Input
placeholder="email@gmail.com"
onChangeText={this.onFieldChange.bind(this, { actionType: 'EMAIL_CHANGED' })}
value={this.props.email}
/>
</Section>
<Section>
<Input
secureTextEntry
placeholder="Password"
onChangeText={this.onFieldChange.bind(this, { actionType: 'PASSWORD_CHANGED' })}
value={this.props.password}
/>
</Section>
<Section>
<Button
onPress={this.LoginAction.bind(this)}
style={styles.buttonLogin}
>
Submit
</Button>
</Section>
</ScrollView>
</View>
</KeyboardAvoidingView>
);
}
}
const mapStateToProps = ({ auth }) => {
console.log(auth);
return auth;
};
export default connect(mapStateToProps, { fieldChange, LoginAction })(LoginCmp);
路由器文件( Router.js ):
const RouterComponent = StackNavigator({
login: { screen: LoginCmp },
dashboard: { screen: DashboardCmp },
});
动作创建者文件( AuthActions.js ):
import firebase from 'firebase';
import { NavigationActions } from 'react-navigation';
// Login actions
export const LoginAction = (payload) => {
return (dispatch) => {
firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)
.then(user => loginSuccess(dispatch, user))
.catch((error) => {
loginFail(dispatch, error);
});
};
};
// Login success function
logoutSuccess = (dispatch, user) => {
// dispatch an action
dispatch({
type: 'LOGOUT_SUCCESS',
payload: user
});
### From here i want to navigate to dashboard.
};
答案 0 :(得分:3)
您还没有指定导航状态是否保存在Redux中,所以如果没有,您肯定应该整合react-navigation和Redux。
react-navigation documentation on how to do it非常清楚。
之后,导航变成另一个调度,只有动作来自react-navigation:
dispatch(NavigationActions.navigate({
routeName: 'dashboard',
}));
在反应导航的重大改写之后,不鼓励与Redux集成。但是,有一些新工具可以让您从任何地方控制导航。例如,请参阅提供此功能的how to create a NavigationService
答案 1 :(得分:3)
v2在2018年的解决方案:
1)定义NavigationService.js文件
import { NavigationActions } from 'react-navigation';
let navigator;
function setTopLevelNavigator(navigatorRef) {
navigator = navigatorRef;
}
function navigate(routeName, params) {
navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
}),
);
}
export default {
navigate,
setTopLevelNavigator,
};
2)在App.js
内,您应具有以下内容:(之前设置了redux提供程序,商店和顶级导航器)
import AppNavigation from 'route-to-NavigationService';
<Provider store={store}>
<TopLevelNavigator
ref={(navigatorRef) => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
</Provider>
3)从您的动作中了解: 从“ route-to-NavigationService”导入NavigationService;
function logIn(){
//async code
...
dispatch(() => {
NavigationService.navigate('RouteNameToNav'),
});
}
额外:如果您想重置导航堆栈(即“登录名”应重置导航堆栈),则在您的调度内,您应该执行以下操作:
dispatch(() => {
StackActions.reset({
index: 0,
actions: [NavigationService.navigate('App')],
});
});
答案 2 :(得分:2)
我有一个快速简单的解决方案:
在必须导航到特定屏幕的情况下,可以将导航作为参数传递给redux动作创建器功能
单独行动的示例:
Redux操作:
export function handleLogout(navigation) {
return (dispatch) => {
dispatch(handleLoggingOut(true));
setTimeout(() => {
STORAGE.removeData('@FunnyLive:token').then(() => {
dispatch(handleLoggingOut(false));
navigation.navigate({routeName: 'Auth'});
})
}, 2000);
}
}
mapDispatchToProps:
const mapDispatchToProps = (dispatch) => ({
logout: (navigation) => dispatch(handleLogout(navigation))
})
最后,您必须这样调用操作:
() => this.props.logout(this.props.navigation);
答案 3 :(得分:0)
import firebase from 'firebase';
import { NavigationActions } from 'react-navigation';
// Login actions
export const LoginAction = (payload) => {
return (dispatch) => {
firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)
.then(user => loginSuccess(dispatch, user))
.catch((error) => {
loginFail(dispatch, error);
});
};
};
// Login success function
logoutSuccess = (dispatch, user) => {
// dispatch an action
dispatch({
type: 'LOGOUT_SUCCESS',
payload: user
});
const navigateAction = NavigationActions.navigate({
routeName: "dashboard",
params: {},
action: NavigationActions.navigate({ routeName: "dashboard" })
});
this.props.navigation.dispatch(navigateAction); // this is where you use navigation prop
};
//将此nav reducer添加到root reducer
import Root from 'your navigation root path';
const navReducer = (state, action) => {
const newState = Root.router.getStateForAction(action, state)
return newState || state
}
export default navReducer;
答案 4 :(得分:0)
对我有用的一种骇人听闻的方式是,您可以将导航道具发送给您的操作
<Button rounded block onPress={() => this.props.nav(this.props.navigation)}>
<Text>
nav
</Text>
</Button>
然后在您的操作文件中:
export function navAction(navigation) {
return (dispatch) => {
navigation.navigate('yourRoute')
}
}
答案 5 :(得分:0)
在导航5和Redux中
例如,我有登录组件
const LoginScreen = (props) => {
return (
<View style={styles.continer}>
<Login navigation={props.navigation}/>
</View>
)
}
在组件Login中,我具有登录功能
import { connect} from 'react-redux';
import {userLogin} from './action/userAction';
const login =()=>{
const {username,password, navigation } = props;
userLogin(username,password, navigation )
}
const mapStateToProps = (state) => {
return{
username:state.auth.username,
password:state.auth.password,
}
};
export default connect(mapStateToProps,{userLogin})(Login) ;
和userAction文件中
export const userLogin = (username, password, navigation) => {
return dispatch => {
// .... any code
loginSucess(dispatch, navigation)
}
}
const loginSucess = (dispatch, navigation) => {
dispatch({
type: USER_LOGIN_SUCSESS,
})
navigation.replace("Home")
}