如何使用 React Router 将数据从一个页面传递到另一个页面

问题描述 投票:0回答:5

我需要有关 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>
    );
  }
}


javascript reactjs react-router-dom
5个回答
26
投票

选项一:通过路由状态

在路由转换中发送状态。

  • 使用

    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();
    

    Edit lucid-kowalevski-uxgs4

  • 使用

    react-router-dom
    v6

    声明式导航 - LinkNavigate 组件

    链接 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();
    

    Edit how-to-pass-data-from-a-page-to-another-page-using-react-router (forked)

选项 2:在 URL 路径中传递一些东西

<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
)。

选项 3:在 URL queryString 中传递 Something

  • 使用

    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

    声明式导航 - LinkNavigate 组件

    链接 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 类组件

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);

参考文献


0
投票

您可以使用

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>
}

0
投票

这就是将数据传递给导航组件的方式

<Link
  to={{
    pathname: '/home/userDetails',
    state: {infoId: info.id},
  }}
>

在导航组件中像这样访问

如果它是基于类的组件。

this.props.location.state

如果是功能组件

props.location.state

0
投票

如果您在 React 应用程序中使用功能组件。您可以按照以下步骤

主页:

<Link
  to={{
    pathname: '/your/path',
    state: { 
       data: "your data"
    },
  }}
>

在您的子页面或您要路由的页面中:

使用 useLocation(版本 5.+)挂钩

const emp = useLocation()

console.log(emp)

输出

{ 
   state: { 
       data: "your data" 
   } 
}

0
投票
**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;
© www.soinside.com 2019 - 2024. All rights reserved.