I'm a React newbie, came across an interesting challenge to create "fake ecommerce page" with this api.
My Products.js file is this. I get api response and save it to a state(console logging it in one line to make sure it's working). You click on a SVG icon of + sign and that item gets "added" to the cart(don't want to add whole item for now, but just make it seems like it's adding it with setCartItems(cartItems + 1) so only number increases). Only thing is that the cart icon is in Header.js component, and I need to pass it there somehow. I've tried with props but couldn't get it to work.
Any help is very much appreciated since I want to learn from your code.
import React from 'react'
import {useState, useEffect} from 'react'
import axios from 'axios'
import plus from '../images/plus.svg'
export default function Products(props) {
const [products, setProducts] = useState([])
const [cartItems, setCartItems] = useState(0)
const updateCart = () => {
setCartItems(cartItems + 1)
console.log(cartItems)
}
useEffect(() => {
axios({
method: 'GET',
url: 'https://api.escuelajs.co/api/v1/products'
}).then((response) => {
setProducts(response.data)
console.log(response.data)
})
}, [])
return (
<section className="bg-white py-8">
<div className="container mx-auto flex items-center flex-wrap pt-4 pb-12">
<nav id="store" className="w-full z-30 top-0 px-6 py-1">
<div
className="w-full container mx-auto flex flex-wrap items-center justify-between mt-0 px-2 py-3">
<a className="uppercase tracking-wide no-underline hover:no-underline font-bold text-gray-800 text-xl "
href="#">
Store
</a>
<div className="flex items-center" id="store-nav-content">
<a className="pl-3 inline-block no-underline hover:text-black" href="#">
<svg className="fill-current hover:text-black" xmlns="http://www.w3.org/2000/svg"
width="24" height="24" viewBox="0 0 24 24">
<path d="M7 11H17V13H7zM4 7H20V9H4zM10 15H14V17H10z"></path>
</svg>
</a>
<a className="pl-3 inline-block no-underline hover:text-black" href="#">
<svg className="fill-current hover:text-black" xmlns="http://www.w3.org/2000/svg"
width="24" height="24" viewBox="0 0 24 24">
<path
d="M10,18c1.846,0,3.543-0.635,4.897-1.688l4.396,4.396l1.414-1.414l-4.396-4.396C17.365,13.543,18,11.846,18,10 c0-4.411-3.589-8-8-8s-8,3.589-8,8S5.589,18,10,18z M10,4c3.309,0,6,2.691,6,6s-2.691,6-6,6s-6-2.691-6-6S6.691,4,10,4z"></path>
</svg>
</a>
</div>
</div>
</nav>
{
products.slice(0, 20).map((product) => {
return (
<div className="w-full md:w-1/3 xl:w-1/4 p-6 flex flex-col" key={product.id}>
<div>
<img className="hover:grow hover:shadow-lg" src={product.category.image}
alt={product.description}/>
<div className="pt-3 flex items-center justify-between">
<p className="uppercase font-bold text-lg">{product.title}</p>
<img src={plus} width='20px' onClick={updateCart} alt={product.description}/>
</div>
<p className="pt-1 text-left text-gray-900">{product.price} €</p>
</div>
</div>
)
}
)
}
</div>
</section>
)
}
This is my Header.js file.
import React from 'react'
export default function Header() {
return (
<nav id="header" className="w-full z-30 top-0 py-1">
<div className="w-full container mx-auto flex flex-wrap items-center justify-between mt-0 px-6 py-3">
<label className="cursor-pointer md:hidden block">
<svg className="fill-current text-gray-900" xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 20 20">
<title>menu</title>
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"></path>
</svg>
</label>
<input className="hidden" type="checkbox" id="menu-toggle" />
<div className="hidden md:flex md:items-center md:w-auto w-full order-3 md:order-1" id="menu">
<nav>
<ul className="md:flex items-center justify-between text-base text-gray-700 pt-4 md:pt-0">
<li><a className="inline-block no-underline hover:text-black hover:underline py-2 px-4" href="#">Shop</a></li>
<li><a className="inline-block no-underline hover:text-black hover:underline py-2 px-4" href="#">About</a></li>
</ul>
</nav>
</div>
<div className="order-1 md:order-2">
<a className="flex items-center tracking-wide no-underline hover:no-underline font-bold text-gray-800 text-xl " href="#">
<svg className="fill-current text-gray-800 mr-2" xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24">
<path d="M5,22h14c1.103,0,2-0.897,2-2V9c0-0.553-0.447-1-1-1h-3V7c0-2.757-2.243-5-5-5S7,4.243,7,7v1H4C3.447,8,3,8.447,3,9v11 C3,21.103,3.897,22,5,22z M9,7c0-1.654,1.346-3,3-3s3,1.346,3,3v1H9V7z M5,10h2v2h2v-2h6v2h2v-2h2l0.002,10H5V10z"></path>
</svg>
NORDICS
</a>
</div>
<div className="order-2 md:order-3 flex items-center" id="nav-content">
<a className="inline-block no-underline hover:text-black" href="#">
<svg className="fill-current hover:text-black" xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24">
<circle fill="none" cx="12" cy="7" r="3"></circle>
<path d="M12 2C9.243 2 7 4.243 7 7s2.243 5 5 5 5-2.243 5-5S14.757 2 12 2zM12 10c-1.654 0-3-1.346-3-3s1.346-3 3-3 3 1.346 3 3S13.654 10 12 10zM21 21v-1c0-3.859-3.141-7-7-7h-4c-3.86 0-7 3.141-7 7v1h2v-1c0-2.757 2.243-5 5-5h4c2.757 0 5 2.243 5 5v1H21z"></path>
</svg>
</a>
<a className="pl-3 inline-block no-underline hover:text-black" href="#">
<svg className="fill-current hover:text-black" xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24">
<path d="M21,7H7.462L5.91,3.586C5.748,3.229,5.392,3,5,3H2v2h2.356L9.09,15.414C9.252,15.771,9.608,16,10,16h8 c0.4,0,0.762-0.238,0.919-0.606l3-7c0.133-0.309,0.101-0.663-0.084-0.944C21.649,7.169,21.336,7,21,7z M17.341,14h-6.697L8.371,9 h11.112L17.341,14z"></path>
<circle cx="10.5" cy="18.5" r="1.5"></circle>
<circle cx="17.5" cy="18.5" r="1.5"></circle>
</svg>
<div className="inline-flex absolute top-4 justify-center items-center w-5 h-5 text-xs font-bold text-white bg-red-500 rounded-full">NUMBER OF ITEMS IN CART GOES HERE</div>
</a>
</div>
</div>
</nav>
)
}
And finally, if needed, this is my App.js file.
import './App.css';
import About from './components/About';
import Header from './components/Header';
import Hero from './components/Hero';
import Products from './components/Products';
function App() {
return (
<div className="App">
<Header />
<Hero />
<Products />
<About />
</div>
);
}
export default App;