diff --git a/.eslintrc.js b/.eslintrc.js
index 1b4e795..3ceadf9 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -23,7 +23,8 @@ module.exports = {
},
plugins: [
'react',
- 'prettier'
+ 'prettier',
+ 'react-hooks'
],
rules: {
'prettier/prettier':'error',
@@ -35,6 +36,8 @@ module.exports = {
'react/state-in-constructor': 'off',
'react/static-property-placement': 'off',
'no-console': ["error", {allow: ["tron"]}],
- 'no-param-reassign': 'off'
+ 'no-param-reassign': 'off',
+ 'react-hooks/rules-of-hooks': 'error',
+ 'react-hooks/exhaustive-deps': 'warn'
},
};
diff --git a/package.json b/package.json
index eb6b2fc..15127aa 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,6 @@
"immer": "^6.0.2",
"intl": "^1.2.5",
"polished": "^3.5.0",
- "prop-types": "^15.7.2",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-flash-message": "^0.1.15",
@@ -47,7 +46,7 @@
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.19.0",
- "eslint-plugin-react-hooks": "^2.5.0",
+ "eslint-plugin-react-hooks": "^2.5.1",
"jest": "^25.1.0",
"metro-react-native-babel-preset": "^0.58.0",
"prettier": "^1.19.1",
diff --git a/src/components/Header/index.js b/src/components/Header/index.js
index cb65d01..fdfe137 100644
--- a/src/components/Header/index.js
+++ b/src/components/Header/index.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { connect } from 'react-redux';
+import { useSelector } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import Icon from 'react-native-vector-icons/MaterialIcons';
@@ -12,7 +12,9 @@ import {
AmountText,
} from './styles';
-function Header({ cartSize }) {
+export default function Header() {
+ const cartSize = useSelector(state => state.cart.length);
+
const navigation = useNavigation();
return (
@@ -27,7 +29,3 @@ function Header({ cartSize }) {
);
}
-
-export default connect(state => ({
- cartSize: state.cart.length,
-}))(Header);
diff --git a/src/pages/Cart/index.js b/src/pages/Cart/index.js
index 72b9d4a..d3b990d 100644
--- a/src/pages/Cart/index.js
+++ b/src/pages/Cart/index.js
@@ -1,7 +1,5 @@
import React from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
+import { useDispatch, useSelector } from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialIcons';
import {
Container,
@@ -31,12 +29,30 @@ import Header from '../../components/Header';
import * as CartActions from '../../store/modules/cart/actions';
-function Cart({ cart, total, removeFromCart, updateAmountRequest }) {
+export default function Cart() {
+ const total = useSelector(state =>
+ formatPrice(
+ state.cart.reduce((totalSum, product) => {
+ return totalSum + product.price * product.amount;
+ }, 0)
+ )
+ );
+
+ const cart = useSelector(state =>
+ state.cart.map(product => ({
+ ...product,
+ subtotal: formatPrice(product.price * product.amount),
+ }))
+ );
+
+ const dispatch = useDispatch();
+
function increment(product) {
- updateAmountRequest(product.id, product.amount + 1);
+ dispatch(CartActions.updateAmountRequest(product.id, product.amount + 1));
}
+
function decrement(product) {
- updateAmountRequest(product.id, product.amount - 1);
+ dispatch(CartActions.updateAmountRequest(product.id, product.amount - 1));
}
return (
@@ -67,7 +83,9 @@ function Cart({ cart, total, removeFromCart, updateAmountRequest }) {
removeFromCart(product.id)}
+ onPress={() =>
+ dispatch(CartActions.removeFromCart(product.id))
+ }
>
@@ -96,27 +114,3 @@ function Cart({ cart, total, removeFromCart, updateAmountRequest }) {
);
}
-
-Cart.propTypes = {
- cart: PropTypes.arrayOf(PropTypes.object).isRequired,
- total: PropTypes.string.isRequired,
- removeFromCart: PropTypes.func.isRequired,
- updateAmountRequest: PropTypes.func.isRequired,
-};
-
-const mapStateToProps = state => ({
- cart: state.cart.map(product => ({
- ...product,
- subtotal: formatPrice(product.price * product.amount),
- })),
- total: formatPrice(
- state.cart.reduce((total, product) => {
- return total + product.price * product.amount;
- }, 0)
- ),
-});
-
-const mapDispatchToProps = dispatch =>
- bindActionCreators(CartActions, dispatch);
-
-export default connect(mapStateToProps, mapDispatchToProps)(Cart);
diff --git a/src/pages/Home/index.js b/src/pages/Home/index.js
index e3b392f..7757420 100644
--- a/src/pages/Home/index.js
+++ b/src/pages/Home/index.js
@@ -1,7 +1,5 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
+import React, { useState, useEffect } from 'react';
+import { useSelector, useDispatch } from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialIcons';
import {
Container,
@@ -22,74 +20,59 @@ import * as CartActions from '../../store/modules/cart/actions';
import { formatPrice } from '../../util/format';
import api from '../../services/api';
-class Home extends Component {
- state = {
- products: [],
- };
+export default function Home() {
+ const [products, setProducts] = useState([]);
- static propTypes = {
- addToCartRequest: PropTypes.func.isRequired,
- amount: PropTypes.objectOf(PropTypes.number).isRequired,
- };
+ const amount = useSelector(state =>
+ state.cart.reduce((sumAmount, product) => {
+ sumAmount[product.id] = product.amount;
- async componentDidMount() {
- const response = await api.get('products');
+ return sumAmount;
+ }, {})
+ );
- const data = response.data.map(product => ({
- ...product,
- priceFormatted: formatPrice(product.price),
- }));
+ const dispatch = useDispatch();
- this.setState({ products: data });
- }
-
- handleAddProduct = id => {
- const { addToCartRequest } = this.props;
-
- addToCartRequest(id);
- };
+ useEffect(() => {
+ async function loadProducts() {
+ const response = await api.get('products');
- render() {
- const { products } = this.state;
- const { amount } = this.props;
+ const data = response.data.map(product => ({
+ ...product,
+ priceFormatted: formatPrice(product.price),
+ }));
+ setProducts(data);
+ }
+ loadProducts();
+ }, []);
- return (
-
-
- String(product.id)}
- renderItem={({ item }) => (
-
-
- {item.title}
- {item.priceFormatted}
- this.handleAddProduct(item.id)}>
-
-
- {amount[item.id] || 0}
-
-
- ADD TO CART
-
-
- )}
- />
-
- );
+ function handleAddProduct(id) {
+ dispatch(CartActions.addToCartRequest(id));
}
-}
-const mapStateToProps = state => ({
- amount: state.cart.reduce((amount, product) => {
- amount[product.id] = product.amount;
-
- return amount;
- }, {}),
-});
-
-const mapDispatchToProps = dispatch =>
- bindActionCreators(CartActions, dispatch);
-
-export default connect(mapStateToProps, mapDispatchToProps)(Home);
+ return (
+
+
+ String(product.id)}
+ renderItem={({ item }) => (
+
+
+ {item.title}
+ {item.priceFormatted}
+ handleAddProduct(item.id)}>
+
+
+ {amount[item.id] || 0}
+
+
+ ADD TO CART
+
+
+ )}
+ />
+
+ );
+}