admin管理员组

文章数量:1277271

I have an actionCreators in my /actions/authenticate.jsto seperate the logic of the actions dispatched by redux and the ponent of react.

Here is my authenticate.js which is my actionCreators

export function login(email, password) { // Fake authentication function
    return async dispatch => {
        dispatch(loginRequest()); // dispatch a login request to update the state
        try {
            if (email.trim() === "[email protected]" && password === "123456") { //If the email and password matches
                const session = { token: "abc1234", email: email, username: "test123" } // Create a fake token for authentication
                await AsyncStorage.setItem(DATA_SESSION, JSON.stringify(session)) // Stringinfy the session data and store it
                setTimeout(() => { // Add a delay for faking a asynchronous request
                    dispatch(loginSuccess(session)) // Dispatch a successful sign in after 1.5 seconds
                    return Promise.resolve()
                }, 1500)
            } else { // Otherwise display an error to the user
                setTimeout(() => { // Dispatch an error state
                    dispatch(loginFailed("Incorrect email or password"))
                }, 1500)
            }
        } catch (err) { // When something goes wrong
            console.log(err)
            dispatch(loginFailed("Something went wrong"));
            return Promise.reject()
        }
    };
} // login

Then I import that in my someComponent.js to import that actionCreator and bind it using bindActionCreators.

Something like this below:

import { bindActionCreators } from "redux";
import * as authActions from "../actions/authenticate";
import { connect } from "react-redux";

Then I connect that action to my ponent which is the Login.js

export default connect(
    state => ({ state: state.authenticate }),
    dispatch => ({
        actions: bindActionCreators(authActions, dispatch)
    })
)(Login);

So I can invoke the function in that actionCreator directly in the Login.js

Something like this below:

onPress={() => {                                 
   this.props.actions.login(this.state.email, this.state.password)
}}

But what I want to happen is this function will dispatch an redux action and also return a Promise if that is possible?

Something like this:

onPress={() => {                                 
       this.props.actions.login(this.state.email, this.state.password)
       .then(() => this.props.navigation.navigate('AuthScreen'))
    }}

What I want to happen is when I try to sign in. Dispatch those asynchronous redux thunk actions and as well return a promise. If is been resolved or not so I can redirect or navigate to the correct screen.

Appreciate if someone could help. Thanks in advance.

I have an actionCreators in my /actions/authenticate.jsto seperate the logic of the actions dispatched by redux and the ponent of react.

Here is my authenticate.js which is my actionCreators

export function login(email, password) { // Fake authentication function
    return async dispatch => {
        dispatch(loginRequest()); // dispatch a login request to update the state
        try {
            if (email.trim() === "[email protected]" && password === "123456") { //If the email and password matches
                const session = { token: "abc1234", email: email, username: "test123" } // Create a fake token for authentication
                await AsyncStorage.setItem(DATA_SESSION, JSON.stringify(session)) // Stringinfy the session data and store it
                setTimeout(() => { // Add a delay for faking a asynchronous request
                    dispatch(loginSuccess(session)) // Dispatch a successful sign in after 1.5 seconds
                    return Promise.resolve()
                }, 1500)
            } else { // Otherwise display an error to the user
                setTimeout(() => { // Dispatch an error state
                    dispatch(loginFailed("Incorrect email or password"))
                }, 1500)
            }
        } catch (err) { // When something goes wrong
            console.log(err)
            dispatch(loginFailed("Something went wrong"));
            return Promise.reject()
        }
    };
} // login

Then I import that in my someComponent.js to import that actionCreator and bind it using bindActionCreators.

Something like this below:

import { bindActionCreators } from "redux";
import * as authActions from "../actions/authenticate";
import { connect } from "react-redux";

Then I connect that action to my ponent which is the Login.js

export default connect(
    state => ({ state: state.authenticate }),
    dispatch => ({
        actions: bindActionCreators(authActions, dispatch)
    })
)(Login);

So I can invoke the function in that actionCreator directly in the Login.js

Something like this below:

onPress={() => {                                 
   this.props.actions.login(this.state.email, this.state.password)
}}

But what I want to happen is this function will dispatch an redux action and also return a Promise if that is possible?

Something like this:

onPress={() => {                                 
       this.props.actions.login(this.state.email, this.state.password)
       .then(() => this.props.navigation.navigate('AuthScreen'))
    }}

What I want to happen is when I try to sign in. Dispatch those asynchronous redux thunk actions and as well return a promise. If is been resolved or not so I can redirect or navigate to the correct screen.

Appreciate if someone could help. Thanks in advance.

Share Improve this question asked Feb 13, 2019 at 0:39 KnowledgeSeekerKnowledgeSeeker 1,0982 gold badges21 silver badges46 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Your first approach was mostly correct. dispatch(thunkAction()) (or in your case this.props.actions.login() returns whatever thunkAction() returns, so it does return Promise in case it's async.

The problem is what that Promise resolves to, which is whatever you return from the async function. In your case, you don't wait for setTimeout and just return void regardless of whether credentials were correct or not.

So, in terms of async functions you'd need something like

export function login(email, password) { // Fake authentication function
    return async dispatch => {
        dispatch(loginRequest()); // dispatch a login request to update the state
        try {
            if (email.trim() === "[email protected]" && password === "123456") { //If the email and password matches
                const session = { token: "abc1234", email: email, username: "test123" } // Create a fake token for authentication
                await AsyncStorage.setItem(DATA_SESSION, JSON.stringify(session)) // Stringinfy the session data and store it
                // Add a delay for faking a asynchronous
                await new Promise((resolve, reject) => setTimeout(() => resolve(), 1500));
                dispatch(loginSuccess(session));
                return Promise.resolve(true);
            } else { // Otherwise display an error to the user
                await new Promise((resolve, reject) => setTimeout(() => resolve(), 1500));
                dispatch(loginFailed("Incorrect email or password"))
                return Promise.resolve(false);
            }
        } catch (err) { // When something goes wrong
            console.log(err)
            dispatch(loginFailed("Something went wrong"));
            return Promise.reject()
        }
    };
} // login

That way, your async function resolves to true/false that you can use in your ponent:

onPress={() => {                                 
       this.props.actions.login(this.state.email, this.state.password)
       .then((login_succeeded) => this.props.navigation.navigate('AuthScreen'))
    }}

You can also return dispatch(loginSuccess(session)); (as long as it's thunk that returns it and not the setTimeout handler), in which case loginSuccess(session) is what .then() will get in your onPress hook.

In case you need to redirect user to another page depending on login result, you should use Redux Router, then in your login thunk you shoud dispatch an appropriate navigation action which will redirect your user to the correct page.

本文标签: javascriptReturning a dispatch with promises in action creators of react reduxStack Overflow