成功操作后重定向到特定页面 - Redux saga
Redirect to a specific page after successful action - Redux saga
我有一个用户个人资料页面,用户可以在其中更新数据。提交数据后,应将其重定向到仪表板页面。
MyProfile.js
handleProfileUpdate = () => {
let user = this.state;
this.props.updateUserProfile(user);
}
动作定义如下
export const updateUserProfile = (obj) => ({
type: types.USER_PROFILE_UPDATE_REQUEST,
payload: obj
});
Saga文件定义如下。
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()
]);
}
但是代码 yield put(push('/dashboard')) 没有重定向到页面。
知道如何解决这个问题吗?
我自己创建了一个解决方案
history.js
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export default history;
将历史文件导入 saga
import history from '../../history';
修改watcher saga如下。
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);
}
}
现在,您需要按如下方式定义 forwardTo 函数。
function forwardTo(location) {
history.push(location);
}
您需要将历史对象推送到不同的路径。
- 如果你可以在你的动作中传递历史对象,你可以直接
写 history.push('/dashboard').
- 你传入一个回调函数
调用操作的操作并调用该回调
使用 yield put(callback()) 函数,以便您可以重定向
使用第 1 点中提到的相同命令。
- window.location.href = 'dashboard';
这是我一直在做的事情的一个简单示例,也是我发现使它起作用的唯一方法:(带 sagas 的打字稿)
MyCreateUserComponent.tsx
onHandleDelete() {
const { push } = this.props.history
const meta: ISagaActionMeta = {
redirect: push,
path: '/users'
}
// call Actioncreator
DeleteUser(userId, meta)
}
actioncreator DeleteUser
看起来像这样:
export const DeleteUser = (userId: number, meta: ISagaActionMeta): ISagaAction<number> => {
return {
type: Actions.user.USER_DELETE,
payload: userId,
meta
}
}
关于我的故事...我做了删除用户所需的操作(调用 api、bla、bla),然后我调用:
yield call(action.meta.redirect, action.meta.path)
整个想法就是将推送功能与其余数据一起传递,并在需要时使用它。
这是我所做的并且有效(接受的答案对我不起作用):
在你的减速器中,你添加了一个布尔变量来指示你的请求是否成功。所以你有如下内容:
case USER_PROFILE_UPDATE_SUCCESS:
return {
...state,
userProfileUpdated: true
}
};
userProfileUpdated
明显是初始化为false.
现在,在您的组件中,您执行如下操作:
render() {
const { myReducer } = this.props;
if (myReducer.userProfileUpdated) {
return this.renderRedirect(ROUTES.DASHBOARD);
} else {
return this.renderUserProfileComponent();
}
}
一旦您的用户配置文件已成功更新,您的 userProfileUpdated
变量将切换为 true,并且您的 MyProfile
组件将 re-render 加载您的 Redirect
组件您将使用 /dashboard
作为路径名从 react-router-dom
导入。
我有一个用户个人资料页面,用户可以在其中更新数据。提交数据后,应将其重定向到仪表板页面。
MyProfile.js
handleProfileUpdate = () => {
let user = this.state;
this.props.updateUserProfile(user);
}
动作定义如下
export const updateUserProfile = (obj) => ({
type: types.USER_PROFILE_UPDATE_REQUEST,
payload: obj
});
Saga文件定义如下。
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()
]);
}
但是代码 yield put(push('/dashboard')) 没有重定向到页面。
知道如何解决这个问题吗?
我自己创建了一个解决方案
history.js
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export default history;
将历史文件导入 saga
import history from '../../history';
修改watcher saga如下。
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);
}
}
现在,您需要按如下方式定义 forwardTo 函数。
function forwardTo(location) {
history.push(location);
}
您需要将历史对象推送到不同的路径。
- 如果你可以在你的动作中传递历史对象,你可以直接 写 history.push('/dashboard').
- 你传入一个回调函数 调用操作的操作并调用该回调 使用 yield put(callback()) 函数,以便您可以重定向 使用第 1 点中提到的相同命令。
- window.location.href = 'dashboard';
这是我一直在做的事情的一个简单示例,也是我发现使它起作用的唯一方法:(带 sagas 的打字稿)
MyCreateUserComponent.tsx
onHandleDelete() {
const { push } = this.props.history
const meta: ISagaActionMeta = {
redirect: push,
path: '/users'
}
// call Actioncreator
DeleteUser(userId, meta)
}
actioncreator DeleteUser
看起来像这样:
export const DeleteUser = (userId: number, meta: ISagaActionMeta): ISagaAction<number> => {
return {
type: Actions.user.USER_DELETE,
payload: userId,
meta
}
}
关于我的故事...我做了删除用户所需的操作(调用 api、bla、bla),然后我调用:
yield call(action.meta.redirect, action.meta.path)
整个想法就是将推送功能与其余数据一起传递,并在需要时使用它。
这是我所做的并且有效(接受的答案对我不起作用):
在你的减速器中,你添加了一个布尔变量来指示你的请求是否成功。所以你有如下内容:
case USER_PROFILE_UPDATE_SUCCESS:
return {
...state,
userProfileUpdated: true
}
};
userProfileUpdated
明显是初始化为false.
现在,在您的组件中,您执行如下操作:
render() {
const { myReducer } = this.props;
if (myReducer.userProfileUpdated) {
return this.renderRedirect(ROUTES.DASHBOARD);
} else {
return this.renderUserProfileComponent();
}
}
一旦您的用户配置文件已成功更新,您的 userProfileUpdated
变量将切换为 true,并且您的 MyProfile
组件将 re-render 加载您的 Redirect
组件您将使用 /dashboard
作为路径名从 react-router-dom
导入。