Advertisement
Guest User

Untitled

a guest
Aug 14th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.55 KB | None | 0 0
  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. );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement