使用 redux ownProps 在道具中获取反应路由器路径
Get react router path in props with redux ownProps
我正在尝试获取容器中 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 组件内,语义 ui 菜单组件会将 activePath
与其自身的路径进行比较并突出显示活动按钮。
理论上一切似乎都可行;当我点击菜单的不同部分时,会发出 @@router/LOCATION_CHANGE
动作。在 redux 开发工具中,我看到状态在变化。但是,永远不会调用 mapStateToProps
并且永远不会重新呈现此组件。
有什么想法吗?我考虑过使用像shouldComponentUpdate
这样的反应方法,但似乎反应甚至没有意识到状态或道具正在改变。
首先要注意的是,您实际上并没有从商店访问路由器状态。如果您查看 react-router-redux docs,它实际上警告不要这样做
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 读取数据,这只是传递到该容器组件的道具。您引用的 react-router-redux 文档中的示例仅适用于顶级路由组件(作为组件道具传递给 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 会收到您要查找的数据。
我正在尝试获取容器中 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 组件内,语义 ui 菜单组件会将 activePath
与其自身的路径进行比较并突出显示活动按钮。
理论上一切似乎都可行;当我点击菜单的不同部分时,会发出 @@router/LOCATION_CHANGE
动作。在 redux 开发工具中,我看到状态在变化。但是,永远不会调用 mapStateToProps
并且永远不会重新呈现此组件。
有什么想法吗?我考虑过使用像shouldComponentUpdate
这样的反应方法,但似乎反应甚至没有意识到状态或道具正在改变。
首先要注意的是,您实际上并没有从商店访问路由器状态。如果您查看 react-router-redux docs,它实际上警告不要这样做
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 读取数据,这只是传递到该容器组件的道具。您引用的 react-router-redux 文档中的示例仅适用于顶级路由组件(作为组件道具传递给 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 会收到您要查找的数据。