Yassin Mo
Yassin Mo

Reputation: 600

How to display Products By Category in React.js

Hi there I'm Beginner in React I'm using React.js and trying to display Categories from public API and it showed up successfully in my app Now I am trying to display the products for each category separately So that if I click on a specific category, all the products for that category will appear on a separate page

App.js

import React from 'react';
import './App.css';
import {BrowserRouter,Routes,Route} from "react-router-dom";
import Categories from './components/Categories';
import Items from './components/Items';
function App() {


  return (
    <div className="App">
      <BrowserRouter>
        <Routes>
          <Route path="/" exact element={<Categories />}/>
          <Route path="/items" element={<Items />}/>
        </Routes>
        {/* <Items /> */}
      </BrowserRouter>
    </div>
  );
}

export default App;

Categories.js

import React, { useState, useEffect } from 'react';
import '../style/Categories/categories.css'
import axios from 'axios'
const Categories = () => {

    const [categories, setCategories] = useState([])
    useEffect(() => {
        const getCategory = async () => {
            const res = await axios.get('https://api.publicapis.org/categories')
            setCategories(res.data.categories)
            console.log("res.data", res.data);
        }
        getCategory()
    }, [])
    return (
        <>
            <h1 style={{ textAlign: 'center' }}>All Categories</h1>
            <div className="category__wrapper">
                {categories.map(category =>
                    <div key={Math.random()} className="category__item">
                        <h2><a href="#" >{category}</a></h2>
                    </div>
                )}
            </div>
        </>
    )
}

export default Categories

Items.js

import React, { useState, useEffect } from 'react';
import axios from 'axios'
import '../style/Items/items.css'


const Items = () => {
    const [items, setItems] = useState([])
    useEffect(() => {
        const getItems = async () => {
            const result = await axios.get('https://api.publicapis.org/entries')
            setItems(result.data.entries)
            console.log("result.entries", result.data.entries);
        }
        getItems()
    }, [])
    return (
        <div className="item__wrapper">
            {items.map((item) => (
                <div class="ui card" key={item.API}>
                    <div class="content">
                        <div class="header">{item.API}</div>
                    </div>
                    <div class="content">
                        <p>{item.Description}</p>
                        <span>Category: {item.Category}</span>
                    </div>
                    <div class="extra content">
                        <button class="ui button">Show More</button>
                    </div>
                </div>
            ))}
        </div>
    )
}

export default Items

Upvotes: 1

Views: 10795

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17858

logancodemaker's answer is almost corret, but a few things missing.

Basically you need to send the Category to the Items component to be able to filter by category.

1-) Items route must be updated in App.js to accept url parameter.

<Route path="/items/:category" element={<Items />}/>

2-) We use Link component from the react-router-dom package in the Categories.js to dynamically send the category url parameter.

<Link to={`/items/${category}`} >{category}</Link>

3-) In Items.js we are filtering the products by the given category name.

    import { useParams } from 'react-router-dom';
    
    const {category} = useParams(); 
    
    useEffect(() => {
        const getItems = async () => {
            const result = await axios.get('https://api.publicapis.org/entries');

            const allItems = result.data.entries;
            const categoryItems = allItems.filter(item => item.Category === category);
            setItems(categoryItems)
        }
        getItems()
    }, [category])

Upvotes: 3

logancodemaker
logancodemaker

Reputation: 670

In App.js

- <Route path="/items" element={<Items />}/>
+ <Route path="/items/:categoryId" element={<Items />}/>

Categories.js

+ import { Link } from "react-router-dom"

- <h2><a href="#" >{category}</a></h2>

+ <h2>
+   <Link to={`/items/${category.id}`}>{category}</Link>
+ </h2>

Items.js

const Items = () => {
+  const { categoryId } = useParams()

  const [items, setItems] = useState([])

  useEffect(() => {
    const getItems = async () => {
-      const result = await axios.get('https://api.publicapis.org/entries')
+      const result = await axios.get(`https://api.publicapis.org/entries/${categoryId}`)
      setItems(result.data.entries)
      console.log("result.entries", result.data.entries);
    }
    getItems()
  }, [])

Upvotes: 2

Related Questions