使用redux ownProps在props中获取路由器路径

son*_*rte 5 reactjs react-router redux react-router-redux

我正在尝试在容器中获取反应路由器的当前路径,因此我可以将其传递给将改变其可见性过滤器的子组件.

更具体地说,我正在尝试使导航菜单突出显示当前活动的页面.

我正在使用react,redux,react-router和react-router-redux,所以我可以从redux商店访问路由器状态.

来自react-router-redux的文档,它说要做这样的事情:

function mapStateToProps(state, ownProps) {
  return {
    id: ownProps.params.id,
    filter: ownProps.location.query.filter
  };
}
Run Code Online (Sandbox Code Playgroud)

这是我的容器组件:

import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import {
  Segment as UISegment,
} from 'semantic-ui-react'
import NavMenu from '../components/NavMenu'

class MenuBar extends Component {
  static propTypes = {
    path: PropTypes.string.isRequired
  }

  render() {
    const { path, } = this.props

    return (
      <UISegment>
        <NavMenu activePath={path} />
      </UISegment>
    )
  }
}

const mapStateToProps = (state, ownProps) => {   
  return {
    path: ownProps.route ? ownProps.route.path : "/"
  }
}

export default connect(mapStateToProps)(MenuBar)
Run Code Online (Sandbox Code Playgroud)

在NavMenu组件内部,语义菜单组件将activePath与其自己的路径进行比较并突出显示活动按钮.

一切似乎都在理论上起作用; 当我点击菜单的不同部分时,@@router/LOCATION_CHANGE会发出一个动作.在redux dev工具中,我看到状态在变化.但是,mapStateToProps永远不会调用此组件,并且永远不会重新呈现此组件.

有任何想法吗?我想过使用像这样的反应方法shouldComponentUpdate,但似乎反应甚至没有意识到状态或道具正在发生变化.

TLa*_*add 4

首先要注意的是,您实际上并没有从存储中访问路由器状态。如果你查看react-router-redux文档,它实际上警告不要这样做

您不应直接从 Redux 存储中读取位置状态。这是因为 React Router 是异步运行的(以处理动态加载组件之类的事情),并且您的组件树可能尚未与 Redux 状态同步更新。您应该依赖 React Router 传递的 props,因为它们仅在处理完所有异步代码后才会更新。

您的容器正在从 ownProps 读取数据,这只是传递到该容器组件中的 props。您引用的react-router-redux文档中的示例仅适用于顶级路由组件(作为组件属性传递给React Router Route组件的组件)。React Router 将路由器数据传递到所有路由组件中。

在您的情况下,MenuBar 是您的顶级路由组件的子级。你的两个选择是

  1. 将所需的数据从路由组件传递到 MenuBar 中。
  2. 使用React Router的withRouter高阶组件将值注入MenuBar https://github.com/ReactTraining/react-router/blob/v3/docs/API.md#withroutercomponent-options

另外,我相信您正在寻找的值是 ownProps.location.pathname 而不是 ownProps.route.path

选项 1 的一些代码,因为我假设 MenuBar 在组件树中没有嵌套得太深:

如果你的路由配置是

<Router history={browserHistory}>
  <Route path="/" component={AppLayout}>
    <Route path="about" component={About}/>
    <Route path="users" component={Users}/>
    <Route path="*" component={NoMatch}/>
  </Route>
</Router>
Run Code Online (Sandbox Code Playgroud)

你的 AppLayout 会是这样的

const AppLayout = ({ children, location }) => {
  return (
    <div>
      <MenuBar path={ location.pathname } />
      { children }
    </div>
  )
} 
Run Code Online (Sandbox Code Playgroud)

和 MenuBar 将接收您正在寻找的数据。