I use React Redux and I create a function to login, but I need to get a callback return after successfull login and redirect user to a page.
I try to passing function as parameter but not working.
How can I get the return after dispatch action?
Login fun
export const login = (request,cb) => {
return dispatch => {
let url = "/api/user/login";
axios({
method: "post",
url: url,
data: request,
config: { headers: { "Content-Type": "multipart/form-data" } }
})
.then(response => {
let authState = {
isLoggedIn: true,
user: response.data
};
cb();
window.localStorage["authState"] = JSON.stringify(authState);
return dispatch({
type: "USER_LOGIN_FULFILLED",
payload: { userAuthData: response.data }
});
})
.catch(err => {
return dispatch({
type: "USER_LOGIN_REJECTED",
payload: err
});
});
};
};
submiting
handleLogin(e) {
this.setState({ showLoader: true });
e.preventDefault();
const request = new Object();
if (this.validator.allValid()) {
request.email = this.state.email;
request.password = this.state.password;
this.props.login(request, () => {
//get callbach here
this.props.history.push('/my-space/my_views');
})
this.setState({ showLoader: false });
} else {
this.setState({ showLoader: false });
this.validator.showMessages();
this.forceUpdate();
}
}
const mapStateToProps = state => {
return {
authState: state
};
};
const mapDispatchToProps = dispatch => {
return {
login: request => dispatch(login(request))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
I use React Redux and I create a function to login, but I need to get a callback return after successfull login and redirect user to a page.
I try to passing function as parameter but not working.
How can I get the return after dispatch action?
Login fun
export const login = (request,cb) => {
return dispatch => {
let url = "/api/user/login";
axios({
method: "post",
url: url,
data: request,
config: { headers: { "Content-Type": "multipart/form-data" } }
})
.then(response => {
let authState = {
isLoggedIn: true,
user: response.data
};
cb();
window.localStorage["authState"] = JSON.stringify(authState);
return dispatch({
type: "USER_LOGIN_FULFILLED",
payload: { userAuthData: response.data }
});
})
.catch(err => {
return dispatch({
type: "USER_LOGIN_REJECTED",
payload: err
});
});
};
};
submiting
handleLogin(e) {
this.setState({ showLoader: true });
e.preventDefault();
const request = new Object();
if (this.validator.allValid()) {
request.email = this.state.email;
request.password = this.state.password;
this.props.login(request, () => {
//get callbach here
this.props.history.push('/my-space/my_views');
})
this.setState({ showLoader: false });
} else {
this.setState({ showLoader: false });
this.validator.showMessages();
this.forceUpdate();
}
}
const mapStateToProps = state => {
return {
authState: state
};
};
const mapDispatchToProps = dispatch => {
return {
login: request => dispatch(login(request))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
Share
Improve this question
edited Jan 9, 2020 at 2:22
ranieribt
1,3061 gold badge15 silver badges33 bronze badges
asked Jan 8, 2020 at 15:32
Boutamente abdessamadBoutamente abdessamad
5732 gold badges11 silver badges34 bronze badges
5 Answers
Reset to default 2The cb is missing in your connect(...)
Here is the fix
handleLogin(e) {
this.setState({ showLoader: true });
e.preventDefault();
const request = new Object();
if (this.validator.allValid()) {
request.email = this.state.email;
request.password = this.state.password;
this.props.login(request, () => {
//get callbach here
this.props.history.push('/my-space/my_views');
})
this.setState({ showLoader: false });
} else {
this.setState({ showLoader: false });
this.validator.showMessages();
this.forceUpdate();
}
}
const mapStateToProps = state => {
return {
authState: state
};
};
const mapDispatchToProps = dispatch => {
return {
login: (request, cb) => dispatch(login(request, cb))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
Hope it helps:)
If you are using redux-thunk
, you can return a Promise
from your async action
.
The function called by the thunk middleware can return a value, that is passed on as the return value of the dispatch method. In this case, we return a promise to wait for. This is not required by thunk middleware, but it is convenient for us.
But I prefer use useEffect
or ponentDidUpdate
for this purpose:
ponentDidUpdate(){
if(this.props.authState.isLoggedIn){
this.props.history.push('/my-space/my_views');
}
}
I remend using the Redux Cool package if you need actions with callback capability.
Instalation
npm install redux-cool
Usage
import {actionsCreator} from "redux-cool"
const my_callback = () => {
console.log("Hello, I am callback!!!")
}
const callbackable_action = actionsCreator.CALLBACKABLE.EXAMPLE(1, 2, 3, my_callback)
console.log(callbackable_action)
// {
// type: "CALLBACKABLE/EXAMPLE",
// args: [1, 2, 3],
// cb: f() my_callback,
// _index: 1
// }
callbackable_action.cb()
// "Hello, I am callback!!!"
When we try to generate an action object, we can pass the callback function as the last argument. actionsCreator
will check and if the last argument is a function, it will be considered as a callback function.
See Actions Creator for more details
react-redux/redux dispatch returns a promise. you can do this if you want to return a value or identify if the request is success/error after being dispatched
Action example
export const fetchSomething = () => async (dispatch) => {
try {
const response = await fetchFromApi();
dispatch({
type: ACTION_TYPE,
payload: response.value
});
return Promise.resolve(response.value);
} catch (error) {
return Promise.reject(error);
}
}
Usage
const foo = async data => {
const response = new Promise((resolve, reject) => {
dispatch(fetchSomething())
.then(v => resolve(v))
.catch(err => reject(err))
});
await response
.then((v) => navigateToSomewhere("/", { replace: true }))
.catch(err => console.log(err));
};
this post is old, but hopefully it will help
Package.json
"react-redux": "^8.0.2"
"@reduxjs/toolkit": "^1.8.5"
How about sending callback function as parameter to action creator? It works for my login logic.
ponent:
// inside the ponent
const loginCallback = () => {
history.push(location.state.referrer);
};
const handleLogin = (loginData) => {
dispatch(loginActionCreator(loginData, loginCallback));
};
action creator:
// inside the action creator
export const loginActionCreator =
(loginData, loginCallback) => (dispatch, getState) => {
dispatch({
type: userActions.setFetchState,
payload: FETCH_STATES.FETCHING,
});
doSRRequest(srEndpoints.login(loginData))
.then((res) => {
dispatch({
type: userActions.setUser,
payload: res,
});
dispatch({
type: userActions.setFetchState,
payload: FETCH_STATES.FETHCED,
});
loginCallback();
})
};