React-router不会为您提供任何匹配的子 Route 的匹配参数,而是根据当前匹配为您提供参数。因此,如果您的路线设置如下
<Route path='/topic' component={Topics} />
在Topics组件中你有一个 Route 像
<Route path=`${match.url}/:topicId` component={Topic} />
现在,如果您的 url/topic/topic1与内部 Route 匹配,但对于 Topics 组件,则匹配的 Route 仍然存在,/topic因此其中没有参数,这是有道理的。
如果您想获取主题组件中匹配的子路由的参数,则需要使用matchPathReact-router 提供的实用程序并针对要获取其参数的子路由进行测试
import { matchPath } from 'react-router'
render(){
const {users, flags, location } = this.props;
const match = matchPath(location.pathname, {
path: '/topic/:topicId',
exact: true,
strict: false
})
if(match) {
console.log(match.params.topicId);
}
return (
<div>
<Route exact path="/topic/:topicId" component={Topic} />
</div>
)
}
编辑:
获取任何级别的所有参数的一种方法是利用上下文并在它们在上下文提供程序中匹配时更新参数。
您需要在 Route 周围创建一个包装器才能正常工作,一个典型的例子看起来像
RouteWrapper.jsx
import React from "react";
import _ from "lodash";
import { matchPath } from "react-router-dom";
import { ParamContext } from "./ParamsContext";
import { withRouter, Route } from "react-router-dom";
class CustomRoute extends React.Component {
getMatchParams = props => {
const { location, path, exact, strict } = props || this.props;
const match = matchPath(location.pathname, {
path,
exact,
strict
});
if (match) {
console.log(match.params);
return match.params;
}
return {};
};
componentDidMount() {
const { updateParams } = this.props;
updateParams(this.getMatchParams());
}
componentDidUpdate(prevProps) {
const { updateParams, match } = this.props;
const currentParams = this.getMatchParams();
const prevParams = this.getMatchParams(prevProps);
if (!_.isEqual(currentParams, prevParams)) {
updateParams(match.params);
}
}
componentWillUnmount() {
const { updateParams } = this.props;
const matchParams = this.getMatchParams();
Object.keys(matchParams).forEach(k => (matchParams[k] = undefined));
updateParams(matchParams);
}
render() {
return <Route {...this.props} />;
}
}
const RouteWithRouter = withRouter(CustomRoute);
export default props => (
<ParamContext.Consumer>
{({ updateParams }) => {
return <RouteWithRouter updateParams={updateParams} {...props} />;
}}
</ParamContext.Consumer>
);
参数提供者.jsx
import React from "react";
import { ParamContext } from "./ParamsContext";
export default class ParamsProvider extends React.Component {
state = {
allParams: {}
};
updateParams = params => {
console.log({ params: JSON.stringify(params) });
this.setState(prevProps => ({
allParams: {
...prevProps.allParams,
...params
}
}));
};
render() {
return (
<ParamContext.Provider
value={{
allParams: this.state.allParams,
updateParams: this.updateParams
}}
>
{this.props.children}
</ParamContext.Provider>
);
}
}
索引.js
ReactDOM.render(
<BrowserRouter>
<ParamsProvider>
<App />
</ParamsProvider>
</BrowserRouter>,
document.getElementById("root")
);
工作演示