代码Sandbox
https://codesandbox.io/s/patches-xy8h2l?file=/src/components/Support/Products/index.js个
通过转到"此处访问驱动程序系统"->;所有产品->;SuperServerLine重新解决此问题
问题是,当页面使用不同的URL重新呈现时,fetchProducts应该重新运行.根据提供的路由参数(productLine
和server
),将运行fetchProducts的不同部分.然而,无论您访问什么URL,这些都始终是未定义的.工作意味着它应该打印三台服务器:"你做到了1"、"胜利2"和"它正在工作3".
您可以通过以下方式更改支持组件来解决该问题:
import { Helmet } from "react-helmet";
import { Route, Routes } from "react-router-dom";
import Products from "./Products";
import Product from "./Product";
import Dashboard from "../Admin/Dashboard";
import XmlDetails from "./Products/XmlDetails";
import "./style.css";
function Support() {
return (
<div className="App">
<Helmet>
<title>Product Support | Dell US</title>
</Helmet>
<Routes>
<Route
path="products/:category?/*"
element={
<div className="support-products">
<Products />
</div>
}
exact
/>
<Route path=":category/:device" element={<Product />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="catalogs" element={<XmlDetails />} />
</Routes>
</div>
);
}
export default Support;
然而,这会 destruct 路由的其他方面.我不清楚为什么参数不能按原样工作.
父组件(Support/index.js)
import { Helmet } from "react-helmet";
import { Route, Routes } from "react-router-dom";
import Products from "./Products";
import "./style.css";
function Support() {
return (
<div className="App">
<Helmet>
<title>Product Support</title>
</Helmet>
<Routes>
<Route
path="products/*"
element={
<div className="support-products">
<Products />
</div>
}
exact
/>
</Routes>
</div>
);
}
export default Support;
子组件(Support/Products/index.js)
import React, { useState, useEffect } from "react";
import {
NavLink,
Link,
Route,
Routes,
useParams,
useLocation
} from "react-router-dom";
import http from "../../http";
import { strCompare } from "../../util";
import "./style.css";
import Alert from "react-bootstrap/Alert";
function Products() {
// Here, 'ProductLine' might be something like "SuperServerLine" or "server 2",
// and 'server' could be something like "server 3".
const { productLine, server } = useParams(); // <- Example values for productLine and server
const location = useLocation();
const [productLines, setProductLines] = useState([]);
const [servers, setServers] = useState([]);
const [authorized, setAuthorized] = useState(null);
console.log("productLine:", productLine); // Debugging line
console.log("server:", server); // Debugging line
useEffect(() => {
if (location.state !== undefined && location.state !== null) {
setAuthorized(location.state.authorized);
}
const fetchProducts = async () => {
if (!productLine) {
try {
const res = await http.get("/api/brands");
if (res.brands.length === 0) {
alert("No product lines available");
} else {
setProductLines(res.brands.sort());
}
} catch (error) {
console.error("Failed to fetch product lines:", error);
}
// If there's a productLine (e.g., "SuperServerLine") but no specific server (e.g., "server 1"),
// fetch the systems for that productLine.
} else if (productLine && !server) {
// The endpoint will include the productLine value (e.g., "/api/systems?brand=SuperServerLine").
try {
const res = await http.get("/api/systems?brand=" + productLine);
if (res.systems.length === 0) {
alert("No servers for this product available");
} else {
res.systems.sort((a, b) => strCompare(a.system_id, b.system_id));
// setServers(res.systems); REMOVING FOR MOCK
setServers(mockServers);
}
} catch (error) {
console.error("Failed to fetch servers:", error);
}
}
};
fetchProducts();
}, [productLine, server, location.state]);
const getBreadCrumbs = () => {
let path = location.pathname.split("/").filter(Boolean);
let crumbs = [];
crumbs.push({ label: "All " + path[0], path: `/${path[0]}/` });
for (let i = 1; i < path.length; i++) {
if (path[i]) {
crumbs.push({
label: path[i],
path: `${crumbs[i - 1].path}${path[i]}/`
});
}
}
return crumbs;
};
return (
<div className="products-content container">
<div className="container-fluid">
<div className="row">
<div className="col-xs-6">
{authorized === false && (
<div className="error-box">
<Alert variant="danger">
Please contact administrator for access to admin page
</Alert>
</div>
)}
</div>
</div>
</div>
<div className="product-nav">
{getBreadCrumbs().map((crumb) => {
return (
<div key={crumb.label}>
<NavLink to={crumb.path} className="breadcrumb-active" end>
{crumb.label}
</NavLink>
<span className="breadcrumb-delim">/</span>
</div>
);
})}
</div>
<div>
<Routes>
<Route
path="/"
element={
<ListProductLines productLines={["SuperServerLine"]} exact />
}
/>
<Route
path=":productLine"
element={<ListServers servers={servers} />}
/>
<Route path=":productLine/:server*" element={<div>We made it</div>} />
</Routes>
</div>
</div>
);
}
// Component to render a list of product lines SuperServerLine, etc
function ListProductLines({ productLines }) {
return (
<div className="product-links row">
{/* Map over the 'productLines' array and render each product */}
{productLines.map((prod, i) => (
<div key={i} className="component-link col-xs-12 col-md-3">
{/* Create a link to the product page using 'renderProductName' to form the URL */}
<Link to={`/products/${prod}`}>
{/* Display the product name using 'renderProductName' */}
{prod}
</Link>
</div>
))}
</div>
);
}
// Function to render a list of products for a specific productLine, e.g., servers R440, R7625, etc.
function ListServers({ servers }) {
return (
<div className="product-links row">
{servers.map((prod, i) => {
return (
<div key={i} className="component-link col-xs-12 col-md-3">
<Link to={`./${prod.system_id}/drivers`}>
{`${prod.brand} ${prod.name}`}
</Link>
</div>
);
})}
</div>
);
}
const mockServers = [
{
system_id: "05CE",
system_id_type: "MULTISYSTEMCHASSIS",
brand: "SuperServerLine",
name: "Server 1",
created_at: "2023-08-16T17:59:22.249Z",
updated_at: "2023-08-16T17:59:22.249Z"
},
{
system_id: "05CF",
system_id_type: "MULTISYSTEMCHASSIS",
brand: "SuperServerLine",
name: "Server 2",
created_at: "2023-08-16T17:59:22.249Z",
updated_at: "2023-08-16T17:59:22.249Z"
},
{
system_id: "05D0",
system_id_type: "MULTISYSTEMCHASSIS",
brand: "SuperServerLine",
name: "Server 3",
created_at: "2023-08-16T17:59:22.249Z",
updated_at: "2023-08-16T17:59:22.249Z"
}
];
export default Products;