diff --git a/src/App.js b/src/App.js
index bdd3b32..af4c329 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,32 +1,25 @@
-import React, { Component } from "react";
+import React, { useState, useEffect } from "react";
import { BrowserRouter, Route } from "react-router-dom";
-
import Home from "./pages/Home";
import NewProduct from "./pages/NewProduct";
-
import * as api from "./api";
const LOCAL_STORAGE_KEY = "react-sc-state";
-
function loadLocalStorageData() {
const prevItems = localStorage.getItem(LOCAL_STORAGE_KEY);
-
if (!prevItems) {
return null;
}
-
try {
return JSON.parse(prevItems);
} catch (error) {
return null;
}
}
-
function buildNewCartItem(cartItem) {
if (cartItem.quantity >= cartItem.unitsInStock) {
return cartItem;
}
-
return {
id: cartItem.id,
title: cartItem.title,
@@ -38,95 +31,67 @@ function buildNewCartItem(cartItem) {
quantity: cartItem.quantity + 1,
};
}
-
-class App extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- products: [],
- cartItems: [],
- isLoading: false,
- hasError: false,
- loadingError: null,
- };
-
- this.handleAddToCart = this.handleAddToCart.bind(this);
- this.handleRemove = this.handleRemove.bind(this);
- this.handleChange = this.handleChange.bind(this);
- this.handleDownVote = this.handleDownVote.bind(this);
- this.handleUpVote = this.handleUpVote.bind(this);
- this.handleSetFavorite = this.handleSetFavorite.bind(this);
- this.saveNewProduct = this.saveNewProduct.bind(this);
- }
-
- componentDidMount() {
- const prevItems = loadLocalStorageData();
-
- if (!prevItems) {
- this.setState({
- isLoading: true,
- });
-
- api.getProducts().then((data) => {
- this.setState({
- products: data,
- isLoading: false,
- });
- });
- return;
+function App() {
+ const [products, setProducts] = useState([]);
+ const [cartItems, setCartItems] = useState([]);
+ const [isLoading, setIsLoading] = useState(false);
+ const [hasError, setHasError] = useState(false);
+ const [loadingError, setLoadingError] = useState(null);
+
+ useEffect(() => {
+ async function loadData() {
+ const prevItems = loadLocalStorageData();
+ if (!prevItems) {
+ setIsLoading(true);
+ try {
+ const productResponse = await api.getProducts();
+ if (productResponse.data) {
+ setProducts(productResponse.data);
+ setIsLoading(false);
+ }
+ } catch (error) {
+ setHasError(true);
+ setIsLoading(false);
+ setLoadingError("Error");
+ }
+ } else {
+ setProducts(prevItems.products);
+ }
+ setCartItems(prevItems.cartItems);
}
+ loadData();
+ }, []);
- this.setState({
- cartItems: prevItems.cartItems,
- products: prevItems.products,
- });
- }
-
- componentDidUpdate() {
- const { cartItems, products } = this.state;
-
+ useEffect(() => {
localStorage.setItem(
LOCAL_STORAGE_KEY,
JSON.stringify({ cartItems, products }),
);
- }
-
- handleAddToCart(productId) {
- const { cartItems, products } = this.state;
+ }, [cartItems, products]);
+ function handleAddToCart(productId) {
const prevCartItem = cartItems.find((item) => item.id === productId);
const foundProduct = products.find((product) => product.id === productId);
-
if (prevCartItem) {
const updatedCartItems = cartItems.map((item) => {
if (item.id !== productId) {
return item;
}
-
if (item.quantity >= item.unitsInStock) {
return item;
}
-
return {
...item,
quantity: item.quantity + 1,
};
});
-
- this.setState({ cartItems: updatedCartItems });
+ setCartItems(updatedCartItems);
return;
}
-
const updatedProduct = buildNewCartItem(foundProduct);
- this.setState((prevState) => ({
- cartItems: [...prevState.cartItems, updatedProduct],
- }));
+ setCartItems([...cartItems, updatedProduct]);
}
-
- handleChange(event, productId) {
- const { cartItems } = this.state;
-
+ function handleChange(event, productId) {
const updatedCartItems = cartItems.map((item) => {
if (item.id === productId && item.quantity <= item.unitsInStock) {
return {
@@ -134,25 +99,15 @@ class App extends Component {
quantity: Number(event.target.value),
};
}
-
return item;
});
-
- this.setState({ cartItems: updatedCartItems });
+ setCartItems(updatedCartItems);
}
-
- handleRemove(productId) {
- const { cartItems } = this.state;
+ function handleRemove(productId) {
const updatedCartItems = cartItems.filter((item) => item.id !== productId);
-
- this.setState({
- cartItems: updatedCartItems,
- });
+ setCartItems(updatedCartItems);
}
-
- handleDownVote(productId) {
- const { products } = this.state;
-
+ function handleDownVote(productId) {
const updatedProducts = products.map((product) => {
if (
product.id === productId &&
@@ -170,16 +125,11 @@ class App extends Component {
},
};
}
-
return product;
});
-
- this.setState({ products: updatedProducts });
+ setProducts(updatedProducts);
}
-
- handleUpVote(productId) {
- const { products } = this.state;
-
+ function handleUpVote(productId) {
const updatedProducts = products.map((product) => {
if (
product.id === productId &&
@@ -196,16 +146,11 @@ class App extends Component {
},
};
}
-
return product;
});
-
- this.setState({ products: updatedProducts });
+ setProducts(updatedProducts);
}
-
- handleSetFavorite(productId) {
- const { products } = this.state;
-
+ function handleSetFavorite(productId) {
const updatedProducts = products.map((product) => {
if (product.id === productId) {
return {
@@ -213,62 +158,45 @@ class App extends Component {
isFavorite: !product.isFavorite,
};
}
-
return product;
});
-
- this.setState({ products: updatedProducts });
+ setProducts(updatedProducts);
}
-
- saveNewProduct(newProduct) {
- this.setState((prevState) => ({
- products: [newProduct, ...prevState.products],
- newProductFormOpen: !prevState.newProductFormOpen,
- }));
- }
-
- render() {
- const {
- cartItems,
- products,
- isLoading,
- hasError,
- loadingError,
- } = this.state;
-
- return (
-
- (
-
- )}
- />
- (
-
- )}
- />
-
- );
+ function saveNewProduct(newProduct) {
+ setProducts((prevProducts) => [...prevProducts, newProduct]);
+ // newProductFormOpen: !prevState.newProductFormOpen
}
+ return (
+
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+
+ );
}
-
export default App;
diff --git a/src/components/NewProductForm/NewProductForm.js b/src/components/NewProductForm/NewProductForm.js
index 3bb3ea1..60c062d 100644
--- a/src/components/NewProductForm/NewProductForm.js
+++ b/src/components/NewProductForm/NewProductForm.js
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React, { useState } from "react";
import { Redirect } from "react-router-dom";
import { v4 as uuid } from "uuid";
import { Formik } from "formik";
@@ -33,171 +33,157 @@ function addProductDetails(product) {
};
}
-class NewProductForm extends Component {
- constructor(props) {
- super(props);
- this.state = {
- submitted: false,
- };
+function NewProductForm({ saveNewProduct }) {
+ const [submitted, setSubmitted] = useState(false);
- this.setSubmitted = this.setSubmitted.bind(this);
- }
-
- setSubmitted() {
+ function setSubmit() {
setTimeout(() => {
- this.setState({
- submitted: true,
- });
+ setSubmitted(true);
}, 500);
}
- render() {
- const { submitted } = this.state;
- const { saveNewProduct } = this.props;
-
- return (
- <>
- {
- const newProduct = addProductDetails(values);
- saveNewProduct(newProduct);
- setSubmitting(true);
- this.setSubmitted();
- }}
- >
- {({
- handleChange,
- handleBlur,
- handleSubmit,
- errors,
- values,
- touched,
- isValidating,
- isValid,
- isSubmitting,
- }) => (
-
- )}
-
- {submitted && }
- >
- );
- }
+ return (
+ <>
+ {
+ const newProduct = addProductDetails(values);
+ saveNewProduct(newProduct);
+ setSubmitting(true);
+ setSubmit();
+ }}
+ >
+ {({
+ handleChange,
+ handleBlur,
+ handleSubmit,
+ errors,
+ values,
+ touched,
+ isValidating,
+ isValid,
+ isSubmitting,
+ }) => (
+
+ )}
+
+ {submitted && }
+ >
+ );
}
export default NewProductForm;