This project was created with create-react-app
, so just run:
npm install
npm run start
๐ก You will see a bunch of warnings but that's okay, they will get fixed along the way.
Inside the file App.jsx
, use the .map() method to print a ProductCard
of each one of the products you have in the products state.
โ ๏ธ Remember that each element inside the map should have a unique key prop- Check the
ProductCard
component to see how it's expecting the props
Click only on times of desperation
import React, { useState } from 'react';
import './App.css';
import productData from './products.json';
import ProductCard from './components/ProductCard';
function App() {
const [products, setProducts] = useState(productData);
return (
<div className="cart">
<h1>My shopping cart</h1>
{/* ITERATION 1 */}
{products.map(elem => {
return <ProductCard product={elem} key={elem._id} />
})}
</div>
);
}
export default App;
Create a function handleDelete
on the App component.
- This function should receive a unique id when called
- This function should filter the products array to update the state with those which weren't deleted
- Send this function to the
ProductCard
child via props - This function should be called from an
onClick
event on your delete button. The function will send the id from the children to the parent and theApp.jsx
file is in charge of filtering it out
Click only when your brain is all over the wall
// App.jsx
import React, { useState } from 'react';
import './App.css';
import productData from './products.json';
import ProductCard from './components/ProductCard';
function App() {
const [products, setProducts] = useState(productData);
// ITERATION 2
const handleDelete = (id) => {
const cleanProducts = [...products].filter(elem => elem._id !== id)
setProducts(cleanProducts)
}
return (
<>
<h1>My shopping cart</h1>
<div className="cart">
{/* ITERATION 1 */}
{products.map(elem => {
return <ProductCard product={elem} key={elem._id} handleDelete={handleDelete} />
})}
</div>
</>
);
}
export default App;
// ProductCard.jsx
import React from 'react'
export default function ProductCard({ product, handleDelete }) {
const { name, price, image, _id } = product;
const handleProductDelete = () => {
// ITERATION 2
handleDelete(_id)
}
return (
<div className="product_card">
<h3>{name}</h3>
<img src={image} alt={name} />
<p>Price: {price}$</p>
<button className="btn_delete" onClick={handleProductDelete}>Delete</button>
</div>
)
}
- Create a
SearchInput
component - This component should display an
input
- Import this component in the
App.jsx
file and display it - Create a
searchValue
state in theApp.jsx
file - In the
App.jsx
file, create a function calledhandleSearch
that will recieve a value (any string) as a parameter and will update thesearchValue
state with said value - Change the code in
App.jsx
so that the ProductCards displayed are only the ones that include the searchValue in theirname
(might want to do something before that map...) - Send this
handleSearch
function from the parent to the child (SearchInput component) so that the component can use it - Everytime the input inside the
SearchInput
component changes, it should call the handleSearch function of the parent and send it thee.target.value
Click only when seriously questioning life choices
// SearchInput.jsx
import React from 'react'
export default function SearchInput({ handleSearch }) {
return (
<div>
<input type="text" placeholder="What are you looking for?" onChange={e => handleSearch(e.target.value)} />
</div>
)
}
// App.jsx
import React, { useState } from 'react';
import './App.css';
import productData from './products.json';
import ProductCard from './components/ProductCard';
import SearchInput from './components/SearchBar';
function App() {
const [products, setProducts] = useState(productData);
const [searchValue, setSearchValue] = useState('');
// ITERATION 2
const handleDelete = (id) => {
const cleanProducts = [...products].filter(elem => elem._id !== id)
setProducts(cleanProducts)
}
// ITERATION 3
const handleSearch = (value) => {
setSearchValue(value)
}
return (
<>
<h1>My shopping cart</h1>
<SearchInput handleSearch={handleSearch} />
<div className="cart">
{/* ITERATION 1 */}
{products
.filter(elem => elem.name.toLowerCase().includes(searchValue.toLocaleLowerCase()))
.map(elem => {
return <ProductCard product={elem} key={elem._id} handleDelete={handleDelete} />
})}
</div>
</>
);
}
export default App;
- Import the
AddProductForm
in theApp.jsx
file and display it - In the
App.jsx
file, create a function calledhandleNewProduct
that will recieve an object containing the new product information, and will add an id to it, and will update the products state with this new addition - Send this function to the child,
AddProductForm
- In the
AddProductForm
, recieve this function as a prop and use it when submitting the form, to send the information of thenewProduct
from the child to the parent
Click only when thinking you shouldn't REALLY be a developer
// AddProduct.jsx
import React, { useState } from 'react'
export default function AddProductForm({ handleNewProduct }) {
const initialState = {
name: '',
image: '',
price: 0
}
const [newProduct, setNewProduct] = useState(initialState);
const handleChange = (e) => {
// ITERATION 4
// Update the state according to the corresponding input
setNewProduct(prev => {
return {
...prev,
[e.target.name]: e.target.value
}
})
}
const handleSubmit = (e) => {
e.preventDefault();
// ITERATION 4
handleNewProduct(newProduct);
setNewProduct(initialState);
}
return (
<div className="form_container">
<form onSubmit={handleSubmit}>
<label>Product name</label>
<input type="text" name="name" value={newProduct.name} onChange={handleChange} required />
<label>Product image</label>
<input type="text" name="image" required value={newProduct.image} onChange={handleChange} />
<label>Product price</label>
<input type="number" name="price" required value={newProduct.price} onChange={handleChange} />
<button type="submit" className="btn">Create</button>
</form>
</div>
)
}
// App.jsx
import React, { useState } from 'react';
import './App.css';
import productData from './products.json';
import ProductCard from './components/ProductCard';
import SearchInput from './components/SearchBar';
import AddProductForm from './components/AddProduct';
function App() {
const [products, setProducts] = useState(productData);
const [searchValue, setSearchValue] = useState('');
// ITERATION 2
const handleDelete = (id) => {
const cleanProducts = [...products].filter(elem => elem._id !== id)
setProducts(cleanProducts)
}
// ITERATION 3
const handleSearch = (value) => {
setSearchValue(value)
}
// ITERATION 4
const handleNewProduct = (prod) => {
const productWithId = { ...prod, _id: products.length + 1 };
setProducts([...products, productWithId]);
}
return (
<>
<h1>My shopping cart</h1>
<SearchInput handleSearch={handleSearch} />
<div className="cart">
{/* ITERATION 1 */}
{products
.filter(elem => elem.name.toLowerCase().includes(searchValue.toLocaleLowerCase()))
.map(elem => {
return <ProductCard product={elem} key={elem._id} handleDelete={handleDelete} />
})}
</div>
<AddProductForm handleNewProduct={handleNewProduct} />
</>
);
}
export default App;
โ All done!! ๐ช๐ผ