From 52ad45325af395ac2d7a0faaa468acfc1e4ad3d0 Mon Sep 17 00:00:00 2001 From: RodrigoTomeES Date: Thu, 12 Dec 2019 11:18:41 +0100 Subject: [PATCH] Updated app to work with Redux (Basic) --- src/containers/BurgerBuilder/BurgerBuilder.js | 143 ++++++------------ src/containers/Checkout/Checkout.js | 40 ++--- .../Checkout/ContactData/ContactData.js | 12 +- src/index.js | 13 +- src/store/actions.js | 2 + src/store/reducer.js | 47 ++++++ 6 files changed, 124 insertions(+), 133 deletions(-) create mode 100644 src/store/actions.js create mode 100644 src/store/reducer.js diff --git a/src/containers/BurgerBuilder/BurgerBuilder.js b/src/containers/BurgerBuilder/BurgerBuilder.js index 32235fa..603393d 100644 --- a/src/containers/BurgerBuilder/BurgerBuilder.js +++ b/src/containers/BurgerBuilder/BurgerBuilder.js @@ -1,5 +1,6 @@ import React, {Component} from 'react'; import axios from '../../axios-orders'; +import {connect} from 'react-redux'; import Aux from '../../hoc/Auxiliary/Auxiliary'; import Burger from '../../components/Burger/Burger'; @@ -8,42 +9,34 @@ import Modal from '../../components/UI/Modal/Modal'; import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary'; import Spinner from '../../components/UI/Spinner/Spinner'; import withErrorHandler from '../../hoc/withErrorHandler/withErrorHandler'; - -const INGREDIENT_PRICES = { - salad: 0.5, - cheese: 0.4, - bacon: 0.7, - meat: 1.3 -} +import * as actionTypes from '../../store/actions'; class BurguerBuilder extends Component { state = { - ingredients: null, - totalPrice: 5, - purchasable: false, purchasing: false, error: false } componentDidMount() { - axios.get('/ingredients.json') - .then(response => { - const ingredients = response.data; - let price = this.state.totalPrice; - for (let ingredient in ingredients) { - price += INGREDIENT_PRICES[ingredient] * ingredients[ingredient]; - } - this.setState({ - ingredients: ingredients, - totalPrice: price - }); - }) - .catch(error => { - this.setState({error: true}); - }); + // axios.get('/ingredients.json') + // .then(response => { + // const ingredients = response.data; + // let price = this.props.price; + // for (let ingredient in ingredients) { + // price += INGREDIENT_PRICES[ingredient] * ingredients[ingredient]; + // } + // this.setState({ + // ingredients: ingredients, + // totalPrice: price + // }); + // }) + // .catch(error => { + // this.setState({error: true}); + // }); } - updatePurchaseState = (ingredients) => { + isPurchasable = () => { + const ingredients = this.props.ings; const sum = Object.keys(ingredients) .map(igkey => { return ingredients[igkey]; @@ -52,57 +45,7 @@ class BurguerBuilder extends Component { return sum + el; }, 0); - this.setState({purchasable: sum > 0}); - } - - addIngredientHandler = (type) => { - // Updating ingredients - const oldCount = this.state.ingredients[type]; - const updateCount = oldCount + 1; - const updatedIngredients = { - ...this.state.ingredients - } - updatedIngredients[type] = updateCount; - - // Updating pricing - const oldPrice = this.state.totalPrice; - const priceAddition = INGREDIENT_PRICES[type]; - const newPrice = oldPrice + priceAddition; - - // Updating state - this.setState({ - ingredients: updatedIngredients, - totalPrice: newPrice, - }); - - // Updating purchasable - this.updatePurchaseState(updatedIngredients); - } - - removeIngredientHandler = (type) => { - // Updating ingredients - const oldCount = this.state.ingredients[type]; - // You can't have negative ingredients - if (oldCount <= 0) return; - const updateCount = oldCount - 1; - const updatedIngredients = { - ...this.state.ingredients - } - updatedIngredients[type] = updateCount; - - // Updating pricing - const oldPrice = this.state.totalPrice; - const priceDeduction = INGREDIENT_PRICES[type]; - const newPrice = oldPrice - priceDeduction; - - // Updating state - this.setState({ - ingredients: updatedIngredients, - totalPrice: newPrice, - }); - - // Updating purchasable - this.updatePurchaseState(updatedIngredients); + return sum > 0; } purchaseHandler = () => { @@ -114,48 +57,38 @@ class BurguerBuilder extends Component { } purchaseContinuedHandler = () => { - const queryParams = []; - for (let ingredient in this.state.ingredients) { - queryParams.push(encodeURIComponent(ingredient) + '=' + encodeURIComponent(this.state.ingredients[ingredient])); - } - queryParams.push('price=' + this.state.totalPrice); - const queryString = queryParams.join('&'); - - this.props.history.push({ - pathname: '/checkout', - search: queryString - }); + this.props.history.push('/checkout'); } render() { const disableInfo = { - ...this.state.ingredients + ...this.props.ings } for (let key in disableInfo) { disableInfo[key] = disableInfo[key] <= 0; } let orderSummary = null; let burger = this.state.error ?

Ingredients can't be loaded!

: ; - if (this.state.ingredients) { + if (this.props.ings) { burger = ( - + ); orderSummary = ; } return ( @@ -169,4 +102,18 @@ class BurguerBuilder extends Component { } } -export default withErrorHandler(BurguerBuilder, axios); +const mapStateToProps = state => { + return { + ings: state.ingredients, + price: state.totalPrice + }; +}; + +const mapDispatchToProps = dispatch => { + return { + onIngredientAdded: (ingName) => dispatch({type: actionTypes.ADD_INGREDIENT, ingredientName: ingName}), + onIngredientRemoved: (ingName) => dispatch({type: actionTypes.REMOVE_INGREDIENT, ingredientName: ingName}), + }; +}; + +export default connect(mapStateToProps, mapDispatchToProps)(withErrorHandler(BurguerBuilder, axios)); diff --git a/src/containers/Checkout/Checkout.js b/src/containers/Checkout/Checkout.js index 0151ce0..95154d9 100644 --- a/src/containers/Checkout/Checkout.js +++ b/src/containers/Checkout/Checkout.js @@ -1,33 +1,11 @@ import React, {Component} from 'react'; import {Route} from 'react-router-dom'; +import {connect} from 'react-redux'; import CheckoutSmmary from '../../components/Order/CheckoutSummary/CheckoutSummary'; import ContactData from './ContactData/ContactData'; class Checkout extends Component { - state = { - ingredients: '', - totalPrice: 0 - } - - componentDidMount() { - const query = new URLSearchParams(this.props.location.search); - const ingredients = {}; - let price = 0; - for (let param of query.entries()) { - if (param[0] === 'price') { - price = param[1] - } else { - ingredients[param[0]] = +param[1]; - } - } - - this.setState({ - ingredients: ingredients, - totalPrice: price - }); - } - checkoutCancelledHandler = () => { this.props.history.goBack(); } @@ -40,21 +18,23 @@ class Checkout extends Component { return(
- } + component={ContactData} />
); } } -export default Checkout; +const mapStateToProps = state => { + return { + ings: state.ingredients + }; +}; + +export default connect(mapStateToProps)(Checkout); diff --git a/src/containers/Checkout/ContactData/ContactData.js b/src/containers/Checkout/ContactData/ContactData.js index 164a71a..0d0c6d7 100644 --- a/src/containers/Checkout/ContactData/ContactData.js +++ b/src/containers/Checkout/ContactData/ContactData.js @@ -1,5 +1,6 @@ import React, {Component} from 'react'; import { withRouter } from "react-router-dom"; +import {connect} from 'react-redux'; import classes from './ContactData.module.css'; import Button from '../../../components/UI/Button/Button'; @@ -104,7 +105,7 @@ class ContactData extends Component { formData[formElementIdentifier] = this.state.orderForm[formElementIdentifier].value; } const order = { - ingredients: this.props.ingredients, + ingredients: this.props.ings, price: this.props.price, orderData: formData } @@ -203,4 +204,11 @@ class ContactData extends Component { } } -export default withRouter(ContactData); \ No newline at end of file +const mapStateToProps = state => { + return { + ings: state.ingredients, + price: state.totalPrice + }; +}; + +export default connect(mapStateToProps)(withRouter(ContactData)); \ No newline at end of file diff --git a/src/index.js b/src/index.js index 24aebf6..894fdd9 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,22 @@ import React from 'react'; import ReactDOM from 'react-dom'; import {BrowserRouter} from 'react-router-dom'; +import {Provider} from 'react-redux'; +import {createStore} from 'redux'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; +import reducer from './store/reducer'; + +const store = createStore(reducer); const app = ( - - - + + + + + ); ReactDOM.render(app, document.getElementById('root')); diff --git a/src/store/actions.js b/src/store/actions.js new file mode 100644 index 0000000..077bb61 --- /dev/null +++ b/src/store/actions.js @@ -0,0 +1,2 @@ +export const ADD_INGREDIENT = 'ADD_INGREDIENT'; +export const REMOVE_INGREDIENT = 'REMOVE_INGREDIENT'; diff --git a/src/store/reducer.js b/src/store/reducer.js new file mode 100644 index 0000000..a4b33f4 --- /dev/null +++ b/src/store/reducer.js @@ -0,0 +1,47 @@ +import * as actionTypes from './actions'; + +const INGREDIENT_PRICES = { + salad: 0.5, + cheese: 0.4, + bacon: 0.7, + meat: 1.3 +} + +const initialState = { + ingredients: { + salad: 0, + cheese: 0, + bacon: 0, + meat: 0 + }, + totalPrice: 5 +}; + +const reducer = (state = initialState, action) => { + let updatedState = { + ...state, + ingredients: { + ...state.ingredients + } + }; + + const ingredient = action.ingredientName; + + switch ( action.type ) { + case actionTypes.ADD_INGREDIENT: + updatedState.ingredients[ingredient] = state.ingredients[ingredient] + 1; + updatedState.totalPrice = state.totalPrice + INGREDIENT_PRICES[ingredient]; + break; + case actionTypes.REMOVE_INGREDIENT: + updatedState.ingredients[ingredient] = state.ingredients[ingredient] - 1; + updatedState.totalPrice = state.totalPrice - INGREDIENT_PRICES[ingredient]; + break; + default: + console.log("Action default case"); + break; + } + + return updatedState; +}; + +export default reducer;