[英]ReactJs Product Details Page
我有一個帶有有效Bearer令牌的API 。
我在產品頁面上列出了API中的所有三種產品。 我希望能夠在我創建的產品項目詳細信息頁面上單擊任何項目並顯示信息。
我已經成功創建了我的路線,我可以點擊並打開相關頁面。 現在的問題是在 ReactJS 中使用params
、 props
和match
在項目詳細信息頁面上提取單個項目的詳細信息。
這是App.js文件
import "./index.scss";
import React from "react";
import {
BrowserRouter as Router,
Route,
Routes,
} from "react-router-dom";
import Discover from "./pages/discover";
import ItemDetail from "./pages/itemDetail";
function App() {
return (
<Router>
<Routes>
<Route path="discover" exact element={<Discover />} />
<Route path="/itemDetail/:productCode" exact element={<ItemDetail />} />
</Routes>
</Router>
);
}
export default App;
這是產品頁面,我將其命名為發現我正在自定義卡片組件上呈現來自 API 的所有產品。
import React, { useState, useEffect } from "react";
import { Row, Col } from "react-bootstrap";
import StyledCard from "../components/Card";
const Discover = (props) => {
const token = "3f224802-426e-3597-a2eb-7d35e6bff31d";
const [result, setResult] = useState([]);
useEffect(() => {
fetch(
"https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/product/",
{
method: "GET",
headers: { Authorization: `Bearer ${token}` },
}
)
.then((res) => res.json())
.then((json) => setResult(json));
}, []);
const cardStyle = {
listStyle: "none",
margin: 5,
paddingLeft: 0,
minWidth: 240,
};
return (
<>
<div className="latestdeals container my-5">
<h1>All Products</h1>
<Row className="hotcards">
<Col className="colcard">
{(result?.result || []).map((item) => (
<div key={item.productCode} style={cardStyle}>
<a href={`/itemDetail/${item.productCode}`}>
{" "}
<StyledCard
key={item.productCode}
name={item.vendor}
title={item.description}
price={item.value}
/>
</a>
</div>
))}
</Col>
</Row>
</div>
</>
);
};
export default Discover;
下面是項目詳細信息頁面,我想在其中顯示該 1 個特定項目中的所有數據。 我還想在將來將該商品添加到購物車(購物車頁面)。
import React, {useEffect, useState} from 'react';
function ItemDetail({ match }) {
const [item, setItem] = useState({});
const token = "3f224802-426e-3597-a2eb-7d35e6bff31d";
useEffect(() => {
fetch(
"https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/product/",
{
method: "GET",
headers: { Authorization: `Bearer ${token}` },
}
)
.then((res) => res.json())
.then((json) => setItem(json));
}, []);
console.log(item);
return (
<div>Item Detail</div>
)
}
export default ItemDetail;
下面終於是我從 API 得到的結果
{
"result": [
{
"description": "PlayStation Store R50 Voucher ",
"productCode": "317",
"value": 50,
"vendor": "Sony PlayStation"
},
{
"description": "R1 - R2500 1Voucher Token",
"productCode": "311",
"value": 0,
"vendor": "1Voucher"
},
{
"description": "Refund 1Voucher Token",
"productCode": "392",
"value": 0,
"vendor": "1Voucher"
}
],
"status": "Success"
}
Discover
組件正在呈現原始錨點 ( <a />
) 標記,而不是react-router-dom
提供的Link
組件。 這將在單擊時重新加載頁面,丟失任何已保存的 React state。ItemDetail
不需要重新獲取與Discover
相同的數據。 一個簡單的解決方案可能是將路由 state 中的特定項目發送到詳細信息頁面。發現
導入Link
組件並用它替換錨標記。 在路由 state 中傳遞當前映射項。記住將響應result
屬性保存到 state 而不是整個結果 object。
import { Link } from 'react-router-dom';
const Discover = (props) => {
const token = "XXXXX";
const [result, setResult] = useState([]);
useEffect(() => {
fetch(
"https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/product/",
{
method: "GET",
headers: { Authorization: `Bearer ${token}` },
}
)
.then((res) => res.json())
.then((data) => setResult(data.result)); // <-- save data.result
}, []);
...
return (
<div className="latestdeals container my-5">
<h1>All Products</h1>
<Row className="hotcards">
<Col className="colcard">
{result.map((item) => (
<div key={item.productCode} style={cardStyle}>
<Link // <-- use Link component
to={`/itemDetail/${item.productCode}`}
state={{ item }} // <-- pass item object in state
>
<StyledCard
key={item.productCode}
name={item.vendor}
title={item.description}
price={item.value}
/>
</Link>
</div>
))}
</Col>
</Row>
</div>
);
};
項目詳情
在react-router-dom@6
中, Route
組件 API 與 v5 相比發生了一些變化,不再有任何route props ,即沒有history
, location
和match
props。
ItemDetail
是一個 function 組件,因此它可以使用 React 掛鈎,特別是useLocation
掛鈎來訪問傳遞的路由 state。由於數據是在路由 state 中傳遞的,因此不需要額外的 GET 請求。
例子:
import React, {useEffect, useState} from 'react';
import { useLocation } from 'react-router-dom';
function ItemDetail() {
const { state } = useLocation(); // <-- access route state
const { item } = state || {}; // <-- unpack the item from state
console.log(item);
return item ? (
<div>
<p>{item.description]</p>
<p>{item.productCode]</p>
<p>{item.value]</p>
<p>{item.vendor]</p>
</div>
) : "No item matched/found.";
}
export default ItemDetail;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.