4

我有一个actionCreators来分离redux调度的动作/actions/authenticate.js的逻辑和react组件

这是我的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);

所以我可以直接在 actionCreator 中调用该函数Login.js

下面是这样的:

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

但是我想要发生的是这个函数将调度一个redux 操作并在可能的情况下返回一个Promise

像这样的东西:

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

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

感谢有人可以提供帮助。提前致谢。

4

2 回答 2

6

您的第一种方法大多是正确的。dispatch(thunkAction())(或者在你的情况下this.props.actions.login()返回任何thunkAction()返回,所以它确实返回 Promise 以防它是async.

问题是 Promise 解决的问题,即您从async函数返回的任何内容。在您的情况下,无论凭据是否正确,您都不会等待setTimeout并返回。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

这样,您的 async 函数将解析为您可以在组件中使用的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));(只要是 thunk 返回它而不是setTimeout处理程序),在这种情况下,你的钩子会得到loginSuccess(session)什么。.then()onPress

于 2019-02-14T00:53:00.453 回答
0

如果您需要根据login结果将用户重定向到另一个页面,您应该使用Redux Router,然后在您的loginthunk 中您应该调度一个适当的导航操作,它将您的用户重定向到正确的页面。

于 2019-02-13T10:55:38.587 回答