另一种选择是使用 Thunk 样式的异步操作(安全/允许有副作用)来处理此问题。
如果您使用 Thunk,您可以将相同的 history 对象注入到您的 <Router> 组件和使用 thunk.withExtraArgument 的 Thunk 操作中,如下所示:
import React from 'react'
import { BrowserRouter as Router, Route, Redirect} from 'react-router-dom'
import { createBrowserHistory } from "history"
import { applyMiddleware, createStore } from "redux"
import thunk from "redux-thunk"
const history = createBrowserHistory()
const middlewares = applyMiddleware(thunk.withExtraArgument({history}))
const store = createStore(appReducer, middlewares)
render(
<Provider store={store}
<Router history={history}>
<Route path="*" component={CatchAll} />
</Router
</Provider>,
appDiv)
然后在你的 action-creators 中,你将有一个 history 实例,它可以安全地与 ReactRouter 一起使用,所以如果你没有登录,你可以触发一个常规的 Redux 事件:
// meanwhile... in action-creators.js
export const notLoggedIn = () => {
return (dispatch, getState, {history}) => {
history.push(`/login`)
}
}
这样做的另一个好处是 url 现在更容易处理,所以我们可以将重定向信息放在查询字符串等上。
您仍然可以尝试在您的 Render 方法中执行此检查,但如果它导致问题,您可以考虑在 componentDidMount 或生命周期的其他地方执行此检查(尽管我也理解坚持使用无状态功能组件的愿望! )
您仍然可以使用 Redux 和 mapDispatchToProps 将动作创建者注入到您的组件中,因此您的组件仍然只是松散地连接到 Redux。