admin管理员组文章数量:1277271
I have an actionCreators in my /actions/authenticate.js
to 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.js
to 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 badges2 Answers
Reset to default 7Your 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
版权声明:本文标题:javascript - Returning a dispatch with promises in action creators of react redux - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741278005a2369842.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论