在 react redux 的动作创建者中返回带有承诺的调度

Returning a dispatch with promises in action creators of react redux

我的 /actions/authenticate.js 中有一个 actionCreators 来分离 调度的 actions 的逻辑reduxreact.

component

这是我的 authenticate.js 这是我的 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() === "test123@nomail.com" && 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

然后我将其导入 someComponent.js 以导入 actionCreator 并使用 bindActionCreators.

绑定它

如下所示:

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

然后我将该操作连接到我的 组件 ,即 Login.js

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

所以我可以直接在 Login.js

中调用那个 actionCreator 中的函数

如下所示:

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

但我想要发生的是这个函数将 dispatch 一个 redux 动作 并且 return 一个 答应如果可以的话?

像这样:

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

我想要发生的是当我尝试登录时。调度那些异步的 redux thunk 操作以及 return 一个承诺。如果问题得到解决,那么我可以重定向或导航到正确的屏幕。

如果有人能提供帮助,我们将不胜感激。 提前致谢。

如果您需要根据 login 结果将用户重定向到另一个页面,您应该使用 Redux Router, then in your login thunk you shoud dispatch an appropriate navigation action 将用户重定向到正确的页面。

您的第一种方法大部分是正确的。 dispatch(thunkAction())(或者在你的情况下 this.props.actions.login() returns 任何 thunkAction() returns,所以它 return 保证万一它是 async.

问题在于 Promise 解决的问题,即您从 async 函数 return 得到的任何内容。在您的情况下,无论凭据是否正确,您都不会等待 setTimeout 而只是 return void

因此,就异步函数而言,您需要类似

的东西
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() === "test123@nomail.com" && 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

这样,您的异步函数将解析为您可以在组件中使用的 true/false

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

你也可以 return dispatch(loginSuccess(session));(只要它是 return 它而不是 setTimeout 处理程序),在这种情况下 loginSuccess(session) 就是 .then() 会进入你的 onPress 钩子。