我需要有关 react-router-dom 的帮助,我是图书馆的新手,从那以后似乎可以找到任何解决方案。我从 api 调用中得到三个结果,我在其中映射数据以在 UI 上呈现它,现在我现在需要的是,如果我单击此列表之一上的一行,我希望它带我到一个屏幕只显示我点击的那个东西的详细信息。
import React, { Component } from "react";
export default class User extends Component {
state = { userDetails: "" };
componentDidMount() {
axios.get(`https://urlforapi.com`)
.then(({ data }) => {
this.setState({
userDetails: data
});
});
}
render() {
const { userDetails } = this.state;
return (
<div>
{userDetails
? userDetails.map(info => {
return (
<Link to="/home/userDetails">
<div key={info.id}>
<p>{info.name}</p>
</div>
<div>
<p>{info.age}</p>
</div>
<div>
<p>{info.description}</p>
</div>
</Link>
);
})
: null}
</div>
);
}
}
在路由转换中发送状态。
使用
react-router-dom
v5
声明式导航 - 链接到
您可以传递映射条目独有的一些状态,例如
info.id
以及单击链接时发生的路由推送。这会混淆用户的数据,因为您不会将信息泄露给用户界面(即浏览器)。
<Link
to={{
pathname: '/home/userDetails',
state: { infoId: info.id },
}}
>
命令式导航 - useHistory hook
const history = useHistory();
...
history.push({
pathname: '/home/userDetails',
state: { infoId: info.id },
});
然后您可以从该路由返回的组件上的
location
道具/对象解压状态。如果用户从其他地方导航到 '/home/userDetails'
,请使用守卫,因为 state
可能未定义。
如果通过路由道具:
props.location && props.location.state && props.location.state.infoId
或
props.location?.state?.infoId
如果使用函数组件,那么你也可以使用
useLocation
React 钩子:
const { state: { infoId } = {} } = useLocation();
使用
react-router-dom
v6
链接 API 在 v6 中发生了一些变化,
state
现在是一个 prop.
<Link
to='/home/userDetails'
state={{ infoId: info.id }}
>
或使用
Navigate
组件,v5 Redirect
组件的精神继承者/替代品
<Navigate
to="/home/userDetails"
state={{ infoId: info.id }}
/>
命令式导航 - useNavigate 钩子
const navigate = useNavigate();
...
navigate('/home/userDetails', { state: { infoId: info.id } });
然后,您可以从该路由返回的组件上的
location
对象解压状态。如果用户从其他地方导航到 '/home/userDetails'
,请使用守卫,因为 state
可能未定义。
const { state: { infoId } = {} } = useLocation();
<Link to={`/home/userDetails/${info.id}`>
或(RRDv5)
const history = useHistory();
...
history.push(`/home/userDetails/${info.id}`);
或(RRDv6)
const navigate = useNavigate();
...
navigate(`/home/userDetails/${info.id}`);
并从返回的路由组件中的
match
属性中检索参数。例如,如果路线看起来像这样:
使用
react-router-dom
v5
<Route path="/home/userDetails/:infoId" component={Detail} />
然后在组件中从
match
路由 prop 获取 id:
props.match.params.infoId
在功能组件的情况下,
useParams
React hook:
const { infoId } = useParams();
使用
react-router-dom
v6
<Route path="/home/userDetails/:infoId" element={<Detail />} />
v6只有
useParams
钩子,没有路由道具
const { infoId } = useParams();
用户可以看到这个,但是你不必使用保护模式来访问,因为根据定义它将由路由定义(尽管如果用户输入无效的 id 仍然可以定义
infoID
)。
使用
react-router-dom
v5
声明式导航 - 链接到
<Link
to={{
pathname: '/home/userDetails',
search: `?infoId=${info.id}`,
}}
>
命令式导航 - useNavigate 钩子
const history = useHistory();
...
history.push({
pathname: '/home/userDetails',
search: `?infoId=${info.id}`,
});
然后您可以从该路由返回的组件上的
infoId
道具/对象中解压location
查询参数。
如果通过路由道具:
props.location && props.location.search
或
props.location?.search
如果使用函数组件,那么你也可以使用
useLocation
React 钩子:
const { search } = useLocation();
然后创建一个URLSearchParams对象并访问
infoId
参数。
const searchParams = new URLSearchParams(search);
const infoId = searchParams.get("infoId");
使用
react-router-dom
v6
链接 API 在 v6 中发生了一些变化,
state
现在是一个 prop.
<Link
to={{
pathname: '/home/userDetails',
search: `?infoId=${info.id}`,
}}
>
或使用
Navigate
组件,v5 Redirect
组件的精神继承者/替代品
<Navigate
to={{
pathname: '/home/userDetails',
search: `?infoId=${info.id}`,
}}
/>
命令式导航 - useNavigate 钩子
const navigate = useNavigate();
...
navigate({
pathname: '/home/userDetails',
search: `?infoId=${info.id}`,
});
然后您可以从
infoId
钩子中解压 useSearchParams
查询参数。
const [searchParams] = useSearchParams();
const infoId = searchParams.get("infoId");
v6.4.0 中的新功能是 createSearchParams 实用函数。
<Link
to={{
pathname: '/home/userDetails',
search: createSearchParams({ infoId: info.id}),
}}
>
或
navigate({
pathname: '/home/userDetails',
search: createSearchParams({ infoId: info.id}),
});
在
react-router-dom@6
路线道具和withRouter
HOC被删除。要访问 RRDv6 中的旧“路由道具”,您需要创建自己的 withRouter
HOC 替代品,它可以使用 React 钩子并注入可在 React 类组件中使用的道具。
import { useLocation, useParams, /* other hooks */ } from 'react-router-dom';
const withRouter = WrappedComponent => props => {
const location = useLocation();
const params = useParams();
// other hooks
return (
<WrappedComponent
{...props}
{...{ location, params, /* other hooks */ }}
/>
);
};
装饰组件和访问道具:
class MyComponent extends React.Component {
...
this.props.location.state;
this.props.params;
...etc...
...
};
export default withRouter(MyComponent);
您可以使用
react-router-dom
的路径参数选项。
例子
import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Topic from '../topic'
export default function App() {
return (
<Router>
<div>
<Route path="/topic/:name" component={Topic} />
</div>
</Router>
);
}
传递参数:
import React, { Component } from "react";
import { Link } from 'react-router-dom'
export default class Topics extends Component {
render() {
return <Link to="/topic/someTopicName">Some Topic</Link>;
}
}
在组件中访问路由参数
import React from 'react'
export default function Topic(props) {
return <h1>{props.match.params.name}</h1>
}
这就是将数据传递给导航组件的方式
<Link
to={{
pathname: '/home/userDetails',
state: {infoId: info.id},
}}
>
在导航组件中像这样访问
如果它是基于类的组件。
this.props.location.state
如果是功能组件
props.location.state
如果您在 React 应用程序中使用功能组件。您可以按照以下步骤
主页:
<Link
to={{
pathname: '/your/path',
state: {
data: "your data"
},
}}
>
在您的子页面或您要路由的页面中:
使用 useLocation(版本 5.+)挂钩
const emp = useLocation()
console.log(emp)
输出
{
state: {
data: "your data"
}
}
**Pass the state:**
import { Link} from "react-router-dom";
<Link to="/home/userDetails" state: { userDetails:'Name'} }>
**Received the state:**
import { useLocation} from 'react-router-dom';
const location = useLocation();
const userDetails= location.state.userDetails;