我的/actions/authenticate.js
中有一个 actionCreators ,用于区分 redux 和组件的反应。
这是我的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
如下所示:
onPress={() => {
this.props.actions.login(this.state.email, this.state.password)
}}
但是我想发生的是,此功能将调度一个 redux操作,并在可能的情况下返回一个承诺?>
类似这样的东西:
onPress={() => {
this.props.actions.login(this.state.email, this.state.password)
.then(() => this.props.navigation.navigate('AuthScreen'))
}}
我想发生的事情是当我尝试登录时。调度这些异步redux thunk操作并返回一个promise。如果已解决,则可以重定向或导航到正确的屏幕。
感谢有人可以帮助您。 预先感谢。
答案 0 :(得分:1)
您的第一种方法基本上是正确的。 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
这样,您的异步函数解析为可以在组件中使用的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));
(只要返回它的重击而不是setTimeout
处理程序),在这种情况下,loginSuccess(session)
就是.then()
onPress
钩子。
答案 1 :(得分:0)
万一您需要根据login
的结果将用户重定向到另一页,则应使用Redux Router,然后在login
进行批量处理时,应分派适当的navigation action会将您的用户重定向到正确的页面。