SHARE
TWEET

Untitled

a guest Aug 14th, 2019 58 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import './index.css';
  4. const productsList = [
  5.     {
  6.       sku: "first_product",
  7.       title: "Fishsticks",
  8.       price: 8.99
  9.     },
  10.     {
  11.       sku: "second_product",
  12.       title: "Pineapple Pen",
  13.       price: 3.99
  14.     },
  15.     {
  16.       sku: "third_product",
  17.       title: "Krabby Patty Secret Formula",
  18.       price: 19.99
  19.     }
  20.   ];
  21.  
  22.   // createReducer function
  23.   const createReducer = products => {
  24.     return (state, action) => {
  25.       const prodList = products;
  26.  
  27.       switch (action.type) {
  28.         case "ADD_TO_CART":
  29.           // determine if valid product
  30.           if (prodList.find(product => product.sku === action.payload.sku)) {
  31.             let newState1 = [...state];
  32.  
  33.             // increment cart item quantity if exists
  34.             if (newState1.find(item => item.product.sku === action.payload.sku)) {
  35.               window.console.log(`Increment ${action.payload.sku} fired`);
  36.               ++newState1.find(item => item.product.sku === action.payload.sku)
  37.                 .quantity;
  38.             } else {
  39.               window.console.log(`Pushed ${action.payload.sku} product onto cart.`);
  40.               newState1.push({
  41.                 quantity: 1,
  42.                 product: prodList.find(
  43.                   product => product.sku === action.payload.sku
  44.                 )
  45.               });
  46.             }
  47.             return newState1;
  48.           }
  49.  
  50.           // if not valid product return previous state
  51.           return state;
  52.  
  53.         case "SUBTRACT_FROM_CART":
  54.           let newState2 = [...state];
  55.  
  56.           // determine if product exists
  57.           if (newState2.find(item => item.product.sku === action.payload.sku)) {
  58.             // retrieve item
  59.             const item = state.find(
  60.               item => item.product.sku === action.payload.sku
  61.             );
  62.  
  63.             // if quantity is less than 2 remove
  64.             if (item.quantity < 2) {
  65.               window.console.log(`Pop ${action.payload.sku} from cart.`);
  66.               newState2 = newState2.filter(
  67.                 cartItem => cartItem.product.sku != item.product.sku
  68.               );
  69.             } else {
  70.               window.console.log(`Decrement ${action.payload.sku}`);
  71.               --newState2.find(item => item.product.sku === action.payload.sku)
  72.                 .quantity;
  73.             }
  74.             return newState2;
  75.           }
  76.  
  77.           // if not valid product return previous state
  78.           return state;
  79.  
  80.         case "DELETE_FROM_CART":
  81.           let newState3 = state.filter(
  82.             item => item.product.sku != action.payload.sku
  83.           );
  84.           return newState3;
  85.  
  86.         default:
  87.           return state;
  88.       }
  89.     };
  90.   };
  91.  
  92.   // create Context & Provider
  93. /*
  94.   const Context = React.createContext();
  95.   const Provider = props => {
  96.     const [state, dispatch] = React.useReducer(createReducer(productsList), []);
  97.    
  98.     return (
  99.       <Context.Provider value={{ state, dispatch }}>
  100.         {props.children}
  101.       </Context.Provider>
  102.     );
  103.   }
  104. */
  105. // useCallbackでメモ化させる
  106. // reducer による再レンダリングを防ぐ
  107. const Context = React.createContext();
  108. const Provider = props => {
  109.   const memoizedReducer = React.useCallback(createReducer(productsList), [productsList])
  110.   const [state, dispatch] = React.useReducer(memoizedReducer, []);
  111.  
  112.   return (
  113.     <Context.Provider value={{ state, dispatch }}>
  114.       {props.children}
  115.     </Context.Provider>
  116.   );
  117. }
  118.  
  119.   // display component
  120.   const Display = () => {
  121.     const cartContext = React.useContext(Context);
  122.     const [hidden, setHidden] = React.useState(false);
  123.    
  124.     return (
  125.       <div>
  126.         <button onClick={e => {
  127.             e.preventDefault();
  128.             setHidden(hidden ? false : true);
  129.           }}
  130.         >Toggle z-index</button>
  131.         <div
  132.           style={{ backgroundColor: "palevioletred", display: hidden ? "none" : "block" }}
  133.         >
  134.           <h1 style={{ margin: "0" }}>These button should dispatch the "ADD_TO_CART" action.</h1>
  135.           <p>Observe console print statements on initial clicks.</p>
  136.           <div style={{ padding: "20px", display: "flex", justifyContent: "center" }}>
  137.             {productsList.map(product => (
  138.               <div>
  139.                 <button
  140.                   onClick={e => {
  141.                     e.preventDefault();    
  142.                     window.console.log(`${product.sku} ATC button pushed`);
  143.                     cartContext.dispatch({ type: "ADD_TO_CART", payload: { sku: product.sku } });
  144.                   }}
  145.                 >Add {product.title} to Cart</button>
  146.               </div>
  147.             ))}
  148.           </div>
  149.         </div>
  150.         <div style={{ display: hidden ? "none" : "block" }}>
  151.           {cartContext.state.map(item => (
  152.             <div>
  153.               <button onClick={e => {
  154.                   e.preventDefault();
  155.                   window.console.log(`${item.product.sku} INC button pushed`);
  156.                   cartContext.dispatch({ type: "ADD_TO_CART", payload: { sku: item.product.sku } });
  157.                 }}
  158.               >Increment {item.product.title}</button>
  159.               <p>{item.quantity}</p>
  160.               <button onClick={e => {
  161.                   e.preventDefault();
  162.                   window.console.log(`${item.product.sku} DEC button pushed`);
  163.                   cartContext.dispatch({ type: "SUBTRACT_FROM_CART", payload: { sku: item.product.sku } });
  164.                 }}
  165.               >Decrement {item.product.title}</button>
  166.             </div>
  167.           ))}
  168.         </div>
  169.       </div>
  170.     );
  171.   }
  172.  
  173.   ReactDOM.render(
  174.     <Provider>
  175.       <Display />
  176.     </Provider>,
  177.     document.getElementById("root")
  178.   );
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top