在 redux-thunk 中发送注册成功操作后如何执行 history.push 到另一个页面

Posted

技术标签:

【中文标题】在 redux-thunk 中发送注册成功操作后如何执行 history.push 到另一个页面【英文标题】:how to do history.push to another page after dispatch a signup success action in redux-thunk 【发布时间】:2020-07-27 02:23:39 【问题描述】:

我最近在用redux-thunk,遇到这种情况:

在注册操作创建函数中,我想在发送注册成功操作后执行history.push,代码可能如下所示:

// SignupAction.js

export const signupRequest = (userData) => 
  return dispatch => 
    dispatch(signupPending())

    return axios.post('/api/user', userData)
      .then(res => dispatch(signupSuccess()))
      .then(() => 
        // wanna do history.push('/') to the home page after successfully signup
      )
      .catch(error => dispatch(signupFailure(error.message)))
  

现在我很困惑,我试图将所有逻辑放入一个操作中,但无法将history 注入我的注册操作中。我可以给signupRequest 函数提供第二个参数,它可以是history 对象本身:signupRequest(userData, history),或者我可以只传递一个回调:signupRequest(userData, callback)。但是我不确定哪个更好。

还有另一种获取历史记录的方法,我不需要将所有逻辑放在一个动作中,所以signup action 只会简单地返回一个承诺,我稍后会在组件中处理它,在这个在这种情况下,访问history 将非常简单:

// signupAction.js

export const signupRequest = (userData) => 
  return dispatch => 
    return axios.post('/api/users', userData);
  


// signupForm.js
export default class SignupForm extends Component 
  // ...
  handleSubmit = e => 
    const userData = e.target.value
    this.props.signupRequest(userData)
      .then(() => this.props.dispatch(signupSuccess()))
      .then(() => 
        // now i can easily access history inside the component
        this.props.history.push('/')
      )
      .catch(error => dispatch(signupFailure(error.message)))  

那么我应该遵循哪种方式,是否有解决此问题的最佳实践?

【问题讨论】:

【参考方案1】:

不确定这是否是最佳做法,但我看到有些人这样做:solution

关键是将历史记录放在单个文件中,以便我们可以引用它并在组件外部使用它:

首先在独立文件中创建一个history 对象:

// history.js
import  createBrowserHistory  from 'history';

export default createBrowserHistory();

然后将其包裹在Router组件中,一定要使用Router而不是BrowserRouter

import  Router, Route  from 'react-router-dom';
import history from './history';

ReactDOM.render(
  <Router history=history>
    ...
  </Router>
)

最后在 redux actionCreators 中我们可以导入 history 对象并使用它:

// SignupAction.js
import history from './history'

export const signupRequest = (userData) => 
  return dispatch => 
    dispatch(signupPending())

    return axios.post('/api/user', userData)
      .then(res => dispatch(signupSuccess()))
      .then(() => 
        // we are reference/use the same `history` all the time by import it
        history.push('/')
      )
      .catch(error => dispatch(signupFailure(error.message)))
  

所以基本上我还是喜欢把逻辑放在actionCreator里面,组件应该只关注UI渲染,逻辑应该由redux来处理。

【讨论】:

这不会在重定向后呈现页面,可能不再工作了。 @W.Doch 不渲染页面是什么意思,或者您可能有更好的解决方案? 没有其他解决方案。我认为他们改变了一些东西。它会重定向但不呈现页面/组件网络内容。这似乎是一个常见问题(我看到了同样的方法,所以在其他帖子和 cmets 上解决了关于它不再工作的问题) @W.Doch React Router v6 刚刚发布,我看到一些关于如何在 React 上下文之外导航(或 history.push)的问题:***.com/q/61858941/12733140 和 ***.com/q/64192320/12733140。不过目前没有提供解决方案,如果您找到答案,请在下方评论,谢谢!

以上是关于在 redux-thunk 中发送注册成功操作后如何执行 history.push 到另一个页面的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security登录成功后如何处理用户信息

Redux-thunk 异步调用和状态

在 redux-thunk 中调用另一个异步函数

使用 Redux-Thunk / Axios 从 onUploadProgress 事件调度操作

提交数据库php后如何处理电子邮件发送失败

React context dispatch 状态改变后如何处理