将 redux 存储与 react-router 路由位置同步(在路由更改时更新标头) [英] Sync redux store with react-router route location (update header on route change)
问题描述
我正在使用 react-router-redux
并且我正在尝试更新我的应用程序的标题,该标题从商店接收它的状态,每当路由发生变化时 (@@router/UPDATE_LOCATION
)
I am using react-router-redux
and I'm trying to update the header of my app, that receives it's state from the store, whenever the route changes (@@router/UPDATE_LOCATION
)
目前我在 componentWillMount
中分派动作,例如:
Currently I'm dispatching actions in a componentWillMount
like:
componentWillMount() {
this.props.appActions.setHeader('New Block')
}
当我在路由 /blocks/new
上的 componentWillMount
中手动设置标头时,它是路由blocks"的子级,它们都有不同的标头,当我回到history
时,它不起作用,因为路由blocks
的组件没有再次挂载,它仍然挂载.因此头部仍然是New Block
.而不是它自己的标头之前是什么,当 blocks
挂载时,new
仍然作为子项卸载.
When I manually set the header in componentWillMount
on route /blocks/new
, and it is a child of a route 'blocks', who both have a different header, it doesn't work when I go back in history
, because the component of route blocks
does not mount again, it is still mounted. Thus the header is still New Block
. And not what its own header was before, when blocks
mounted, and new
was still unmounted as child.
(当我尝试使用 redux-devtools
来倒转时间时,似乎会发生什么,每次我回到一个组件再次安装的点,它将再次调度该动作,而开发工具将收到另一个调度.)
(And when I try to reverse time with the redux-devtools
, what seems to happen then, every time I go back to a point where a component mounts again, it will dispatch the action again, and the devtool will receive another dispatch.)
路线:
<Route path="begin" component={PlayerBeginContainer}>
<IndexRoute component={PlayerOverview}/>
<Route path="blocks" component={PlayerBlocks}>
<Route path="new" component={PlayerNewBlock}/>
</Route>
</Route>
...
我曾尝试在路线更改时同步商店,但是:
I've tried to sync the store whenever a route changes, but:
if (action && action.type === UPDATE_LOCATION) {
let path = action.payload.pathname.split('/')
// Laboriously iterate through array to figure out what the new header state should be.
// i.e. if (1 in split && split[1] === 'routeName')
// or let lastPath = path[path.length - 1]
// and getting parentPath would require more checking of whether it is the parent itself or not etc.
// appHeader = 'routeHeader'
return Object.assign({}, state, { appHeader: appHeader});
}
当您只需要在特定子路由上触发时,这会变得非常乏味,我想避免创建另一个嵌套结构,而我已经在路由器中定义了该结构.
This gets very tedious when you just need it to trigger on a specific sub-route, And I want to avoid making another nested structure, while I already have that defined in the router.
在标题中,除了 this.props.location.pathname
之外,我不能使用任何其他东西来尝试找出我所在的路线,并且组件本身不应该费心设置标头本身(即在 componentWillMount
中).
In the header I can't use anything other than this.props.location.pathname
either to try and figure out which route i'm on, and the components themselves should not bother with setting the header themselves (i.e. in componentWillMount
).
最后一个选择是使用路由器 onEnter
,但我想保持路由器清洁,但也许我需要在这方面妥协.
Last option would be to use the router onEnter
, but I'd like to keep the router clean, but perhaps I need to compromise on this.
我在这里遗漏了什么吗?或者某种可以帮助我解决这个问题的库?
Is there something I'm missing here? Or some sort of lib that can help me with this?
TL;DR:如何让我的 header
组件知道我们在哪条路线上,而不必分解 location.pathname
来找出我们的位置是吗?
TL;DR: How can I make my header
component aware of which route we are on, without having to break down the location.pathname
to figure out where we are?
推荐答案
这是来自我的代码库之一的代码.在这个应用程序中,我使用哈希历史,但我认为你可以用 其他历史对象也是.
This is code from one of my codebases. In this app i use hash history, but i think you could do same thing with other history objects too.
import {hashHistory} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';
const history = syncHistoryWithStore(hashHistory, store);
history.listen(location => {
// here you can do something after location is updated
});
<Router history={history}>
....
</Router>
然后在你的组件中你可以从 state.routing 获取一些信息:
and then in you components you can get some info from state.routing:
function mapStateToProps(state) {
return {
current: state.routing.locationBeforeTransitions.pathname,
};
}
export default connect(mapStateToProps)(App);
要从某个组件更改路由,请执行以下操作:
To change route from some component, do this:
import {push} from 'react-router-redux';
this.props.dispatch(push('/route'));
这篇关于将 redux 存储与 react-router 路由位置同步(在路由更改时更新标头)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!