【问题标题】:How to pass id to React Js path link?如何将 id 传递给 React Js 路径链接?
【发布时间】:2021-05-07 07:42:09
【问题描述】:

我正在尝试为我的 React Js 项目创建像“/products?id=uniqueId”这样的组件路径。唯一 ID 取自数据库,取决于选择的产品。我的代码是

CodeSandbox

App.js

import "./styles.css";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Products from "./Products"
import Home from "./Home"

export default function App() {
  return (
    <div className="App">
        <Router>
                <Switch>
                <Route exact path="/">
                        {" "}
                        <Home/>
                    </Route>
                    <Route exact path="/products">
                        {" "}
                        <Products />
                    </Route>
                </Switch>
            </Router>
    </div>
  );
}

Home.js

import "./styles.css";
import React, { useState } from "react";
import { useHistory } from "react-router-dom";

const products = [
  {
    id: "1",
    name: "Product 1"
  },
  {
    id: "2",
    name: "Product 2"
  },
  {
    id: "3",
    name: "Product 3"
  }
];

export default function Home() {
  const [id, setId] = useState();
  const history = useHistory();

  const handleProceed = (e) => {
    // console.log(id, "home");
    history.push("/products", { id });
  };

  return (
    <div
      style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
    >
      <div>
        {products.map((product) => {
          return (
            <button
              onClick={(e) => {
                setId(product.id);
              }}
            >
              {product.name}{" "}
            </button>
          );
        })}
      </div>
      <button onClick={handleProceed} style={{ width: "250px" }}>
        {" "}
        Proceed
      </button>
    </div>
  );
}


产品.js

import "./styles.css";
import { useLocation } from "react-router-dom";

export default function Home() {
  const location = useLocation();
  const { id } = location.state || { id: "none" };

  console.log(id);
  return (
    <div>
      <p> Lorem Ipsum</p>
    </div>
  );
}

想法是当用户在 组件中按下任何带有产品名称的按钮时,页面应重定向到 组件,路径应为“/products?id=uniqueId”,其中 uniqueId = 到 product.id。我能够使用 useHistory() 和 useLocation() 将 product.id 从 传递到 ,但我不知道如何使路径显示选定的 id。例如,如果用户单击产品 1 按钮,则到 的路径应该是“/products?id=1”,如果选择了产品 2,路径应该反映为“/products?id=2”等等。

非常感谢任何帮助和建议。

【问题讨论】:

  • 您可以为此使用路由参数而不是查询字符串值。将路由更改为&lt;Route exact path="/products/:id"&gt;,将Products中的id检索更新为const { id } = useParams();并将Home中的history.push更新为history.push("/products/" + id);
  • 同意,将产品 ID 作为路径的一部分与查询字符串相比,可以更简单、更轻松地传递/访问它。如果您对此持开放态度,我可以提出解决方案。

标签: javascript reactjs react-router


【解决方案1】:

我建议将产品 id 作为路径的一部分,而不是将其放在查询字符串中。作为路径的一部分,它几乎不需要您的代码访问,而如果您使用查询字符串,则需要将整个查询字符串解析为键值对映射。

  1. 定义您的路径以包含id

    <Route path="/products/:id">
      <Products />
    </Route>
    
  2. 在产品页面上使用useParams react 钩子来访问id 路由匹配参数。

    const { id } = useParams();
    
  3. id参数生成路径

    const handleProceed = (e) => {
      history.push(generatePath("/products/:id", { id }));
    };
    

    或者如果你喜欢原始的

    const handleProceed = (e) => {
      history.push(`/products/${id}`));
    };
    

我进一步建议通过重新排序您的 Route 组件来优化您的路由,以首先指定更具体的路径。这样可以避免将 exact 属性传递给每条路由。

<Router>
  <Switch>
    <Route path="/products/:id">
      <Products />
    </Route>
    <Route path="/">
      <Home />
    </Route>
  </Switch>
</Router>

演示

完整的演示代码:

import { useState } from "react";
import {
  BrowserRouter as Router,
  generatePath,
  Switch,
  Route,
  useHistory,
  useParams
} from "react-router-dom";

const products = [
  {
    id: "1",
    name: "Product 1"
  },
  {
    id: "2",
    name: "Product 2"
  },
  {
    id: "3",
    name: "Product 3"
  }
];

const Products = () => {
  const { id } = useParams();

  console.log(id);
  return (
    <div>
      <p>Lorem Ipsum</p>
      <p>Id: {id}</p>
    </div>
  );
};

const Home = () => {
  const [id, setId] = useState();
  const history = useHistory();

  const handleProceed = (e) => {
    id && history.push(generatePath("/products/:id", { id }));
  };

  return (
    <div
      style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
    >
      <div>
        {products.map((product, i) => (
          <button
            key={i}
            onClick={(e) => {
              setId(product.id);
            }}
          >
            {product.name}
          </button>
        ))}
      </div>
      <button onClick={handleProceed} style={{ width: "250px" }}>
        Proceed
      </button>
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Router>
        <Switch>
          <Route path="/products/:id">
            <Products />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2021-04-28
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多