skip to Main Content

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…..

2

Answers


  1. There are plenty of solutions to the problem you are describing. Now I want to elaborate on two of them:

    1. 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.

    2. 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!

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search