I am trying to create product detail page, i want to know if we can create it with just useReducer hook or we need Redux for this.....
This is my product page
import React from "react";
import { Link } from "react-router-dom";
import "./RecentlyAdd.css";
import useCard from "../../../Hooks/useStoreCard";
import { Container, Column } from "..//..//../Styled-Components/RecentlyAdd";
export default function RecentlyAdd({ lightBg, imgStart }) {
const { docs } = useCard("Images");
const Products = docs.map((doc) => {
return (
<div className="col-sm-3 m-5">
<div key={doc.id} className="card shadow p-2 mb-3 bg-white rounded">
<img className="card-img-top" src={doc.url} alt="Card image cap" />
<div className="card-body">
<h5 className="card-title">{doc.Title}</h5>
<p className="card-text">{doc.Place}</p>
<p className="card-text">{doc.Year}</p>
<a className="btn btn-primary">
<Link to={`/products/${doc.id}`}>{doc.Title}
</Link>
</a>
</div>
</div>
</div>
);
});
return (
<div
className={lightBg ? "home__hero-section" : "home__hero-section darkBg"}
>
<Container>
<div
className="row"
style={{
display: "flex",
flexDirection: imgStart === "start" ? "row-reverse" : "row",
}}
>
<Column>{Products}</Column>
</div>
</Container>
</div>
);
}
I want to open a new page with all detail when someone clicks on link page opens with product id but i don't know how to add detail i am using firebase do i need redux or i can do it other way like using useReducer hook or something.....
CodePudding user response:
There are plenty of solutions to the problem you are describing. Now I want to elaborate on two of them:
I assume you are using React Router as Routing Library? If not you should probably consider to do so! The easiest solution would be navigating to a route where you set the id of the specific product as param. Then you just get the param from the url by using the function useParams on the detail page and fetch the products detail information from firebase. This avoids adding a heavy library like redux to your project.
You could also use the hook useContext which is already part of ReactJs. An easy example on how to do it can be found here.
Have fun with the solutions!
CodePudding user response:
Here is an example of how you could implement using the context api. Where we use the context to fetch the products and store them in the context state. Then we use that state in both the ProductsPage to show all products and on the ProductDetailsPage to show a specific product.
import {
BrowserRouter,
Link,
useParams,
Route,
Routes
} from "react-router-dom";
import { createContext, useContext } from "react";
export default function App() {
return (
<BrowserRouter>
<ProductsProvider>
<div className="App">
<Routes>
<Route path="/" element={<ProductsPage />} />
<Route path="/product/:id" element={<ProductDetailsPage />}></Route>
</Routes>
</div>
</ProductsProvider>
</BrowserRouter>
);
}
const ProductsContext = createContext({});
const ProductsProvider = ({ children }) => {
const docs = [
{
id: 1,
title: "test",
place: "Place1",
year: "Year1",
url: "url1"
},
{
id: 2,
title: "test2",
place: "Place2",
year: "Year2",
url: "url2"
},
{
id: 3,
title: "test3",
place: "Place3",
year: "Year3",
url: "url3"
}
];
const getProductDetails = (productId) => {
return docs.find((x) => x.id === productId);
};
return (
<ProductsContext.Provider
value={{
docs,
getProductDetails
}}
>
{children}
</ProductsContext.Provider>
);
};
const ProductsPage = () => {
const { docs } = useContext(ProductsContext);
return (
<div>
<h1>Products</h1>
{docs &&
docs.map((doc) => {
return (
<div className="col-sm-3 m-5">
<div
key={doc.id}
className="card shadow p-2 mb-3 bg-white rounded"
>
<img
className="card-img-top"
src={doc.url}
alt="Card image cap"
/>
<div className="card-body">
<h5 className="card-title">{doc.title}</h5>
<p className="card-text">{doc.place}</p>
<p className="card-text">{doc.year}</p>
<a className="btn btn-primary">
<Link to={`/product/${doc.id}`}>{doc.title}</Link>
</a>
</div>
</div>
</div>
);
})}
</div>
);
};
const ProductDetailsPage = () => {
const params = useParams();
const productId = parseInt(params["id"]);
const { getProductDetails } = useContext(ProductsContext);
const product = getProductDetails(productId);
return (
<div>
<h1>Product details for {productId}</h1>
<h3>{product.title}</h3>
<h3>{product.year}</h3>
<Link to="/">Back to products list</Link>
</div>
);
};
Here is the codesandbox link if you want to see it in action: https://codesandbox.io/s/gallant-meninsky-yfpizw