反映导航以从redux操作文件导航

时间:2017-12-22 07:36:54

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

我想从我的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.
};

6 个答案:

答案 0 :(得分:3)

不再有效 - 请参阅

您还没有指定导航状态是否保存在Redux中,所以如果没有,您肯定应该整合react-navigation和Redux。

react-navigation documentation on how to do it非常清楚。

之后,导航变成另一个调度,只有动作来自react-navigation:

dispatch(NavigationActions.navigate({
  routeName: 'dashboard',
}));

编辑:2018年8月9日

在反应导航的重大改写之后,不鼓励与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")
}