在 redux-thunk 中发送注册成功操作后如何对另一个页面执行 history.push
how to do history.push to another page after dispatch a signup success action in redux-thunk
我最近在用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
只是 return 一个承诺,我会处理它稍后在组件中,在这种情况下,访问 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))) }
}
那么我应该采用哪种方式,有什么最佳实践可以解决这个问题吗?
不确定这是否是最佳做法,但我看到有人这样做:
关键是把history放在一个文件里,这样我们就可以在组件外引用和使用它:
首先在独立文件中创建一个 histor
y 对象:
// 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来处理。
我最近在用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
只是 return 一个承诺,我会处理它稍后在组件中,在这种情况下,访问 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))) }
}
那么我应该采用哪种方式,有什么最佳实践可以解决这个问题吗?
不确定这是否是最佳做法,但我看到有人这样做:
关键是把history放在一个文件里,这样我们就可以在组件外引用和使用它:
首先在独立文件中创建一个 histor
y 对象:
// 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来处理。