https://codesandbox.io/s/rr00y9w2wm
要么
match.params.topicId
从这个已解决的问题中我了解到,这不一定是错误。
在需要在工厂Web应用程序中创建运行的用户中,这种要求是非常普遍的,其中Topics父级组件需要访问 match.params.paramId ,其中paramIdURL参数与嵌套(子)组件相匹配Topic:
Topics
paramId
Topic
const Topic = ({ match }) => ( <div> <h2>Topic ID param from Topic Components</h2> <h3>{match.params.topicId}</h3> </div> ); const Topics = ({ match }) => ( <div> <h2>Topics</h2> <h3>{match.params.topicId || "undefined"}</h3> <Route path={`${match.url}/:topicId`} component={Topic} /> ... </div> );
从一般意义上讲,Topics它可以是“抽屉”或“导航菜单”组件,Topic也可以是任何子组件,就像我正在开发的应用程序中一样。子组件具有其自己的:topicId参数,该参数具有其自己(例如)<Route path="sections/:sectionId" component={Section} /> 路由/组件。
:topicId
<Route path="sections/:sectionId" component={Section} />
更加痛苦的是,导航菜单不必与组件树具有一对一的关系。有时,菜单根级的项目(例如Topics,Sections等)可能与 嵌套 结构相对应(Sections仅在“主题”下呈现,/topics/:topicId/sections/:sectionId尽管它具有自己的标准化列表,用户可以在“导航 ” 中的“标题 ” 下找到该列表)酒吧)。因此,当 节 被点击, 就 应当强调,而不是两个 章节 和 主题 。
Sections
/topics/:topicId/sections/:sectionId
由于导航栏组件的sectionId或sections路径在应用程序的根目录级别不可用,因此对于这种常见的用例,有必要像这样编写hack。
sectionId
sections
我根本不是React Router的专家,因此,如果任何人都可以对此用例提出合适的优雅解决方案,我将认为这是富有成果的努力。优雅,我的意思是
match
history.location.pathname
window.location.xxx
this.props.location.pathname
path-to-regexp
TIA!
尝试利用查询参数?来允许父级和子级访问当前选定的topic。不幸的是,您将需要使用模块qs,因为react- router-dom它不会自动解析查询(react-router v3可以)。
?
topic
react- router-dom
工作示例:https : //codesandbox.io/s/my1ljx40r9
URL的结构类似于连接字符串:
topic?topic=props-v-state
然后您将添加到查询中&:
&
/topics/topic?topic=optimization&category=pure- components&subcategory=shouldComponentUpdate
✔使用匹配进行路由URL处理
✔不使用this.props.location.pathname(使用this.props.location.search)
this.props.location.search
✔用于qs解析location.search
qs
location.search
✔不涉及骇客方法
Topics.js
import React from "react"; import { Link, Route } from "react-router-dom"; import qs from "qs"; import Topic from "./Topic"; export default ({ match, location }) => { const { topic } = qs.parse(location.search, { ignoreQueryPrefix: true }); return ( <div> <h2>Topics</h2> <ul> <li> <Link to={`${match.url}/topic?topic=rendering`}> Rendering with React </Link> </li> <li> <Link to={`${match.url}/topic?topic=components`}>Components</Link> </li> <li> <Link to={`${match.url}/topic?topic=props-v-state`}> Props v. State </Link> </li> </ul> <h2> Topic ID param from Topic<strong>s</strong> Components </h2> <h3>{topic && topic}</h3> <Route path={`${match.url}/:topicId`} render={props => <Topic {...props} topic={topic} />} /> <Route exact path={match.url} render={() => <h3>Please select a topic.</h3>} /> </div> ); };
另一种方法是创建一个HOC将参数存储到的state子项,state当子项的参数更改时,子项会更新其父项。
HOC
state
URL的结构类似于文件夹树: /topics/rendering/optimization/pure- components/shouldComponentUpdate
/topics/rendering/optimization/pure- components/shouldComponentUpdate
工作示例:https : //codesandbox.io/s/9joknpm9jy
✔不使用 this.props.location.pathname
✔使用lodash进行对象间比较
import map from "lodash/map"; import React, { Fragment, Component } from "react"; import NestedRoutes from "./NestedRoutes"; import Links from "./Links"; import createPath from "./createPath"; export default class Topics extends Component { state = { params: "", paths: [] }; componentDidMount = () => { const urlPaths = [ this.props.match.url, ":topicId", ":subcategory", ":item", ":lifecycles" ]; this.setState({ paths: createPath(urlPaths) }); }; handleUrlChange = params => this.setState({ params }); showParams = params => !params ? null : map(params, name => <Fragment key={name}>{name} </Fragment>); render = () => ( <div> <h2>Topics</h2> <Links match={this.props.match} /> <h2> Topic ID param from Topic<strong>s</strong> Components </h2> <h3>{this.state.params && this.showParams(this.state.params)}</h3> <NestedRoutes handleUrlChange={this.handleUrlChange} match={this.props.match} paths={this.state.paths} showParams={this.showParams} /> </div> ); }
NestedRoutes.js
import map from "lodash/map"; import React, { Fragment } from "react"; import { Route } from "react-router-dom"; import Topic from "./Topic"; export default ({ handleUrlChange, match, paths, showParams }) => ( <Fragment> {map(paths, path => ( <Route exact key={path} path={path} render={props => ( <Topic {...props} handleUrlChange={handleUrlChange} showParams={showParams} /> )} /> ))} <Route exact path={match.url} render={() => <h3>Please select a topic.</h3>} /> </Fragment> );