redux-react-route v4/v5 push() 在 thunk 动作中不起作用
Posted
技术标签:
【中文标题】redux-react-route v4/v5 push() 在 thunk 动作中不起作用【英文标题】:redux-react-route v4/v5 push() is not working inside thunk action 【发布时间】:2017-12-14 16:52:05 【问题描述】:在index.js
中直接 push 或 throw dispatch 效果很好:
...
import push from 'react-router-redux'
const browserHistory = createBrowserHistory()
export const store = createStore(
rootReducer,
applyMiddleware(thunkMiddleware, routerMiddleware(browserHistory))
)
// in v5 this line is deprecated
export const history = syncHistoryWithStore(browserHistory, store)
history.push('/any') // works well
store.dispatch(push('/any')) // works well
ReactDOM.render((
<Provider store=store>
<Router history=history>
<App />
</Router>
</Provider>
), document.getElementById('root'))
App.js
class App extends Component
render()
return (
<div className="app">
<Switch>
<Route path="/" component=Main />
<Route path="/any" component=Any />
</Switch>
</div>
);
export default withRouter(connect(/*...*/)(App))
但在 redux-thunk
操作中,所有尝试都以重写 url 结束,但 没有重新渲染
...
export function myAction()
return (dispatch) =>
// fetch something and then I want to redirect...
history.push('/any') // change url but not re-render
dispatch(push('/any')) // change url but not re-render
store.dispatch(push('/any')) // change url but not re-render
这个myAction
正在内部调用 fetch() 并且应该在成功后重定向。
如果我在组件内部运行this.props.history.push('/any')
,它就可以工作!但我需要在成功fetch()
我试图用withRouter
或Route
包装所有组件,但没有帮助。
【问题讨论】:
您使用哪个版本的react-router-redux
?您需要使用与react-router
v4 兼容的react-router-redux
v5。 Th 包react-router-redux
v5 目前正在积极开发中。
@oklas 现在我尝试在react-router-redux
v5 上运行它,但它的行为与 v4 相同
这很可能还没有实现。作为解决方法,将此委托给 router
history
对象可用的组件。您的推送事件始终出现在 thunk 队列的末尾,因此您可以使用重定向信息设置状态。
能否提供将history
对象注入您的组件并像这样使用推送:
import withRouter from 'react-router-dom'
import connect from 'react-redux'
@withRouter
@connect((auth)=>(auth))
class App extends Component
// on redux state change
componentWillReceiveProps(nextProps)
if(!nextProps.auth)
this.props.history.push('/login')
render()
return (
<div>
<Button
// on button click
onClick=this.props.history.push('/')
>
Home page
</Button>
</div>
);
【讨论】:
谢谢,看来没有更好的答案了。 谢谢,分享你的快乐。【参考方案2】:我通过将成功 fetch() 的状态委托给 history.push()
或 <Redirect>
工作的组件(感谢@oklas)来解决问题:
this.props.fetchSuccessfull && <Redirect to="/any" />
但仍然通过直接从 thunk 操作调用 push() 来等待更好的解决方案。
【讨论】:
【参考方案3】:那么,让我通过将调度中的历史对象传递给操作来提交另一个不完美的解决方案。我想这更像是一个初学者的解决方案,但恕我直言,易于理解(因此易于维护,这是软件开发中最重要的事情)
使用
我选择坚持使用 BrowserRouter,而不是回到
剩下的唯一选择是将历史对象传递给操作。
在 Auth-ForgotPassword 组件中:
const submitHandler = (data) =>
dispatch(authActions.forgotpassword(data, history:props.history));
在动作函数中
export const forgotpassword = (forgotpasswordData, history) =>
return async dispatch =>
const url = settings.api.hostname + 'auth/forgotpassword'; // Go to the API
const responseData = await fetch(
url,
method: 'POST',
headers:
'Content-Type': 'application/json',
'Accept': 'application/json',
,
body: JSON.stringify(forgotpasswordData),
);
history.push('/auth/forgotpassword/success');
现在我们都在等待最终的优雅解决方案 :-)
【讨论】:
以上是关于redux-react-route v4/v5 push() 在 thunk 动作中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Pytorch深度学习50篇·······第五篇:YOLO----- YOLO V3 V4 V5的模型结构