I have a user profile page where the user can update the data. Once the data is submitted, it should be redirected to dashboard page.
MyProfile.js
handleProfileUpdate = () => {
let user = this.state;
this.props.updateUserProfile(user);
}
Action is defined as follows
export const updateUserProfile = (obj) => ({
type: types.USER_PROFILE_UPDATE_REQUEST,
payload: obj
});
Saga file is defined as follows.
function* updateUserProfile(action) {
try {
let data = action.payload;
yield call(userProvider.updateUserProfile, data);
// dispatch a success action to the store
yield put({ type: types.USER_PROFILE_UPDATE_SUCCESS, data });
yield put(push('/dashboard'));
yield put(constants.successMsg(userProfileUpdateSuccess));
} catch (error) {
// dispatch a failure action to the store with the error
yield put(constants.DEFAULT_ERROR_MSG);
}
}
export function* watchUserProfileUpdateRequest() {
yield takeLatest(types.USER_PROFILE_UPDATE_REQUEST, updateUserProfile);
}
export default function* userSaga() {
yield all([
watchUserProfileRequest(),
watchUserProfileUpdateRequest()
]);
}
But the code yield put(push('/dashboard')) is not redirecting on to the page.
Any idea on how to fix this?
I founded a solution myself
history.js
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export default history;
Import history file into the saga
import history from '../../history';
Modify the watcher saga as follows.
function* updateUserProfile(action) {
try {
let data = action.payload;
yield call(userProvider.updateUserProfile, data);
// dispatch a success action to the store
yield put({ type: types.USER_PROFILE_UPDATE_SUCCESS, data });
yield call(forwardTo, '/dashboard');
yield put(constants.successMsg(userProfileUpdateSuccess));
} catch (error) {
// dispatch a failure action to the store with the error
yield put(constants.DEFAULT_ERROR_MSG);
}
}
Now, you need to define the forwardTo function as follows.
function forwardTo(location) {
history.push(location);
}
This is a simple example of what I've been doing, and the only way I found to make this work: (typescript with sagas)
MyCreateUserComponent.tsx
onHandleDelete() {
const { push } = this.props.history
const meta: ISagaActionMeta = {
redirect: push,
path: '/users'
}
// call Actioncreator
DeleteUser(userId, meta)
}
actioncreator DeleteUser
looks something like this:
export const DeleteUser = (userId: number, meta: ISagaActionMeta): ISagaAction<number> => {
return {
type: Actions.user.USER_DELETE,
payload: userId,
meta
}
}
on my saga... I do what its needed to delete the user (call the api, bla, bla) and then I call:
yield call(action.meta.redirect, action.meta.path)
The entire idea is just to pass the push function together with the rest of the data and use it when needed it.
You need the history object to push to a different path.
Here's what I did and which works (The accepted answer just does not work for me):
In your reducer, you add a boolean variable that will indicate if your request is a success. So you have something as follows:
case USER_PROFILE_UPDATE_SUCCESS:
return {
...state,
userProfileUpdated: true
}
};
userProfileUpdated
is obviously initiated to false.
Now, in your component, you do something as follows:
render() {
const { myReducer } = this.props;
if (myReducer.userProfileUpdated) {
return this.renderRedirect(ROUTES.DASHBOARD);
} else {
return this.renderUserProfileComponent();
}
}
Once your user profile has been successfully updated, your userProfileUpdated
variable will switch to true, and your MyProfile
component will re-render to load your Redirect
component which you will have imported from react-router-dom
with /dashboard
as a pathname.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.