使用 redux ownProps 获取 props 中的 react 路由器路径
我正在尝试获取容器中 React 路由器的当前路径,以便我可以将其传递给将更改其可见性过滤器的子组件。
更具体地说,我正在尝试让导航菜单突出显示当前活动页面。
我正在使用 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
};
}
这是我的容器组件:
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)
在 NavMenu 组件内部,semantic-ui 菜单组件会将
activePath
与其自己的路径进行比较并突出显示活动按钮。
理论上一切似乎都有效;当我单击菜单的不同部分时,会发出
@@router/LOCATION_CHANGE
操作。在 redux 开发工具中,我看到状态发生变化。但是,
mapStateToProps
从未被调用,并且此组件从未重新渲染。
有什么想法吗?我考虑过使用像
shouldComponentUpdate
这样的 React 方法,但 React 似乎甚至没有意识到状态或 props 正在发生变化。
首先要注意的是,您实际上并没有从商店访问路由器状态。如果您查看 react-router-redux 文档 ,它实际上警告不要这样做
You should not read the location state directly from the Redux store. This is because React Router operates asynchronously (to handle things such as dynamically-loaded components) and your component tree may not yet be updated in sync with your Redux state. You should rely on the props passed by React Router, as they are only updated after it has processed all asynchronous code.
您的容器正在从 ownProps 读取数据,这只是传递到该容器组件的 props。您引用的 react-router-redux 文档中的示例仅适用于顶级路由组件(作为组件 prop 传递给 React Router Route 组件的组件)。React Router 将路由器数据传递到所有路由组件。
在您的情况下,MenuBar 是您的顶级路由组件的子项。您的两个选项是
- 将您想要的数据从您的路由组件向下传递到 MenuBar。
- 使用 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>
你的 AppLayout 将会是这样的
const AppLayout = ({ children, location }) => {
return (
<div>
<MenuBar path={ location.pathname } />
{ children }
</div>
)
}
并且 MenuBar 将会收到你正在寻找的数据。