成功执行操作后重定向到特定页面-Redux传奇

时间:2019-04-29 07:28:54

标签: reactjs 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'))不会重定向到页面上。

关于如何解决此问题的任何想法?

4 个答案:

答案 0 :(得分:0)

我自己创建了一个解决方案

history.js

import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export default history;

将历史文件导入传奇

import history from '../../history';

如下修改观察者传奇。

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);
}

答案 1 :(得分:0)

您需要历史记录对象才能推送到其他路径。

  1. 如果您可以在操作中传递历史记录对象,则可以直接 编写 history.push('/ dashboard')
  2. 您在中传递了回调函数 从调用动作的位置调用该动作并调用该回调 yield put(callback())功能,以便您可以重定向 与第1点中提到的命令相同。
  3. window.location.href ='dashboard';

答案 2 :(得分:0)

这是我一直在做的一个简单示例,也是我找到实现此目的的唯一方法:(带sagas的打字稿)

MyCreateUserComponent.tsx

TextEditingController _controller = TextEditingController();

@override
void initState() {
  super.initState();

  _controller.addListener(() {
    setState(() {});
  });
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: TextFormField(
        controller: _controller,
        decoration: InputDecoration(
          suffixIcon: _controller.text.isNotEmpty
              ? IconButton(
                  icon: Icon(Icons.clear, size: 16),
                  onPressed: () {
                    _controller.clear();
                  },
                )
              : null,
        ),
      ),
    ),
  );
}

actioncreator onHandleDelete() { const { push } = this.props.history const meta: ISagaActionMeta = { redirect: push, path: '/users' } // call Actioncreator DeleteUser(userId, meta) } 看起来像这样:

DeleteUser

在我的传奇故事中...我执行删除用户所需的操作(调用api,bla,bla),然后调用:

export const DeleteUser = (userId: number, meta: ISagaActionMeta): ISagaAction<number> => {
  return {
    type: Actions.user.USER_DELETE,
    payload: userId,
    meta
  }
}

整个想法只是将push函数与其余数据一起传递,并在需要时使用它。

答案 3 :(得分:0)

这是我的工作方式,并且有效(接受的答案对我不起作用):

在化简器中,添加一个布尔变量,该变量将指示您的请求是否成功。所以你有以下内容:

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组件将重新呈现以加载您已导入的Redirect组件从react-router-dom/dashboard作为路径名。