将 redux 存储与 react-router 路由位置同步(在路由更改时更新标头) [英] Sync redux store with react-router route location (update header on route change)

查看:38
本文介绍了将 redux 存储与 react-router 路由位置同步(在路由更改时更新标头)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆