React Router Pass Param to Component

const rootEl = document.getElementById('root');


ReactDOM.render(
<BrowserRouter>
<Switch>
<Route exact path="/">
<MasterPage />
</Route>
<Route exact path="/details/:id" >
<DetailsPage />
</Route>
</Switch>
</BrowserRouter>,
rootEl
);

I am trying access the id in the DetailsPage component but it is not being accessible. I tried

<DetailsPage foo={this.props}/>

to pass parameters to the DetailsPage, but in vain.

export default class DetailsPage extends Component {
constructor(props) {
super(props);
}


render() {
return (
<div className="page">
<Header />
<div id="mainContentContainer" >


</div>
</div>
);
}
}

So any idea how to pass the ID on to the DetailsPage ?

251032 次浏览

使用组件:

<Route exact path="/details/:id" component={DetailsPage} />

你应该可以通过以下方式访问 id:

this.props.match.params.id

DetailsPage组件内部

使用渲染方法:

<Route exact path="/details/:id" render={(props) => (
<DetailsPage id={props.match.params.id}/>
)} />

你应该可以通过以下方式访问 id:

this.props.id

在 DetailsPage 组件内部

如果你想把道具传递给路由器内部的一个组件,最简单的方法就是利用 render,像这样:

<Route exact path="/details/:id" render={(props) => <DetailsPage globalStore={globalStore} {...props} /> } />

你可使用以下方法进入 DetailPage内的道具:

this.props.match
this.props.globalStore

{...props}是需要通过原来的路线的道具,否则你将只有 this.props.globalStore内的 DetailPage

我使用它来访问组件中的 ID:

<Route path="/details/:id" component={DetailsPage}/>

在细节部分:

export default class DetailsPage extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
</div>
)
}
}

这将使任何身份内的 h2,希望有人帮助。

除了亚历山大卢纳斯的回答..。 如果要添加多个参数,只需使用:

<Route path="/details/:id/:title" component={DetailsPage}/>


export default class DetailsPage extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
<h3>{this.props.match.params.title}</h3>
</div>
)
}
}

另一种解决方案是在路由组件中使用状态和生命周期挂钩,在 <Link />组件的 to属性中使用搜索语句。以后可以通过 new URLSearchParams()访问搜索参数;

<Link
key={id}
to=\{\{
pathname: this.props.match.url + '/' + foo,
search: '?foo=' + foo
}} />


<Route path="/details/:foo" component={DetailsPage}/>


export default class DetailsPage extends Component {


state = {
foo: ''
}


componentDidMount () {
this.parseQueryParams();
}


componentDidUpdate() {
this.parseQueryParams();
}


parseQueryParams () {
const query = new URLSearchParams(this.props.location.search);
for (let param of query.entries()) {
if (this.state.foo!== param[1]) {
this.setState({foo: param[1]});
}
}
}


render() {
return(
<div>
<h2>{this.state.foo}</h2>
</div>
)
}
}

这是打字稿的版本,可以在 "react-router-dom": "^4.3.1"上使用

export const AppRouter: React.StatelessComponent = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />} />
<Route path="/" exact component={App} />
</Switch>
</BrowserRouter>
);
};

组件

export class ProblemPage extends React.Component<ProblemRouteTokens> {


public render(): JSX.Element {
return <div>{this.props.problemId}</div>;
}
}

ProblemRouteTokens在哪

导出接口问题路由令牌{ }

自从反应路由器 v5.1与钩子:

import { useParams } from 'react-router';


export default function DetailsPage() {
const { id } = useParams();
}

参见 https://reacttraining.com/blog/react-router-v5-1/

如果您正在使用类组件,那么您最有可能使用 GSerjo 建议。通过 <Route>道具传递参数到你的目标组件:

exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />}

试试这个。

<Route exact path="/details/:id" render={(props)=>{return(
<DetailsPage id={props.match.params.id}/>)
}} />

在详细信息页面尝试这个..。

this.props.id

这是用于 response-router-dom v6的(我强烈建议为此使用功能性组件)

不断改变语法和规则对于响应路由器来说有点痛苦,但是这里什么也没有发生。

您可以同时使用 useParamsuseSelector来解决这个问题

import { useParams } from 'react-router';
import { useSelector } from 'react-redux';


const Component = () => {
const { id } = useParams();                              //returns the :id
const page = useSelector((state) => state.something[id]); //returns state of the page


return <div>Page Detail</div>;
}


export default Component;

但是,当您还有一个动作创建器并且您想将它作为一个道具在 connect函数中传递时,问题仍然存在

export const connect(mapStateToProps, mapDispatchToProps)(Component)

因为我们使用的是 useParams,所以它不会传递给我们创建的 mapStateToProps

const mapStateToProps = (state, ownProps) => {
console.log(ownProps)   //wont recognize :id
//hence
return {
someReducers: state.someReducers[id] //would return an error: 'id' is not defined
};
};

另一方面,您不能完全忽略 connect函数,因为您需要 mapDispatchToProps来处理组件。

解决这个问题的方法是自己创建一个高阶组件 withRouter函数。

//make this
import { useParams, useLocation, useNavigate } from 'react-router';
import { connect } from 'react-redux';
import { yourActionCreator } from '../actionCreator';


const withRouter = (Child) => {
return (props) => {
const location = useLocation();
const navigation = useNavigate();
const params = useParams();
return (
<Child
{...props}
params={params}
navigate={navigate}
location={location}
/>
);
};
};


const Component = () => {
// your component...
return <div> Page Detail </div>
};


export mapStateToProps = (state, ownProps) => {
console.log(ownProps)     // would contain the :id params
return {
//something
}
};


const mapDispatchToProps = {
yourActionCreator
}


export withRouter(connect(mapStateToProps, mapDispatchToProps)(Component));

类、 HoC 和路由器 v5的简单示例

包裹 Json

"react-router-dom": "5.3.1",
"react-router": "5.3.1",
"@types/react-router-dom": "5.3.3",
// YourComponent.tsx


import React from 'react';
import { RouteComponentProps, withRouter } from 'react-router';


export interface PathParams {
id: string;
}


export interface Props extends RouteComponentProps<PathParams> {}
export interface State {}


class YourComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {};


console.log(props.match.params) // { id: 1 }
// TypeScript completions
console.log(props.match.params.id) // 1
}


render() {
return <></>;
}
}


export default withRouter(YourComponent);
// App.tsx


import './App.css';


import React from 'react';
import { Route, Switch, Router } from 'react-router-dom';


import YourComponent from './YourComponent';


function App(): JSX.Element {
return (
<Router>
<Switch>
<Route
path="/details/:id"
component={() => <YourComponent />}
/>
</Switch>
</Router>
);
}


export default App;

在最新版本的(response-router-dom@6.3.0)中,你可以这样做:

 <Route path="path" element={<YourComponent type="simple" />} />

这里,类型是传递给 你的组件的输入

我正在研究的反应路由器6.3.0及以上版本的解决方案并没有解决我的问题。然后我使用这样的东西,它工作:

<Route exact path='/payment-status/:userId/:orderId' element={<PaymentStatus/>}/>

在 PaymentStatus.js 页面上,我这样写道:

import { useParams } from 'react-router-dom'


export const PaymentStatus = () => {


let {userId, orderId}=useParams()


return (
<div>
<h2>order ID : {orderId}</h2>
<h2>user ID : {userId}</h2>
</div>
)
}

对我很有效。我希望它能帮到别人。谢谢!

第6版(2022)

注意: 使用 useParams 可以很容易地在组件中获取 params。

看下面的例子

import React from "react";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Home from "./compo/home";
import About from "./compo/about";
import Login from "./compo/login";
import "./styles.css";
const App = () => {
return (
<Router>
<div className="container">
<Link to="/home">Home</Link>
<Link to="/about">About</Link>
<Link to="/login">Login</Link>
</div>
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/login" element={<Login />} />
<Route path="/login/:name" element={<Login />} />
</Routes>
</Router>
);
};
export default App;

登入组件

import { useParams } from "react-router-dom";


const Login = () => {
let { name } = useParams();


return <h1>i am {name ? <b>{name}</b> : "login"}</h1>;
};
export default Login;