另一种选择是使用 Thunk 风格的异步操作(这是安全的/允许有副作用)来处理这个问题。
如果您使用 Thunk,您可以使用 将相同的history
对象注入到您的<Router>
组件和 Thunk 操作中thunk.withExtraArgument
,如下所示:
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。