在 react redux 的动作创建者中返回带有承诺的调度
Returning a dispatch with promises in action creators of react redux
我的 /actions/authenticate.js
中有一个 actionCreators 来分离 调度的 actions 的逻辑redux 和 react.
的 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
钩子。
我的 /actions/authenticate.js
中有一个 actionCreators 来分离 调度的 actions 的逻辑redux 和 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);
所以我可以直接在 Login.js
如下所示:
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
钩子。