fabiobiondi

Context & useReducer

Oct 21st, 2020
1,039
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { createContext, useContext, useReducer } from 'react';
  2.  
  3. interface Counter {
  4.   count: number;
  5.   random: number;
  6. }
  7.  
  8.  
  9. const initialState = {count: 0, random: 0.5};
  10.  
  11. // type Action = {type: 'increment'} | {type: 'setRandom'}
  12. type Actiontype = 'increment' | 'setRandom';
  13. type Action = { type: Actiontype, payload?: any }
  14.  
  15. type Dispatch = (action: Action) => void;
  16.  
  17. function countReducer(state: Counter, action: Action) {
  18.   switch (action.type) {
  19.     case 'increment':
  20.       return { ...state, count: state.count + 1}
  21.     case 'setRandom':
  22.       return { ...state, random: Math.random()}
  23.   }
  24.   return state;
  25. }
  26.  
  27. const CountStateContext = createContext<!!|>(undefined);
  28. const CountDispatchContext = createContext<Dispatch>(() => null);
  29.  
  30. export default function App() {
  31.   const [state, dispatch] = useReducer(countReducer, initialState)
  32.   return <div>
  33.     <CountStateContext.Provider value={state}>
  34.        <CountDispatchContext.Provider value={dispatch}>
  35.         <button onClick={() => dispatch({ type: 'increment'})}>+</button>
  36.         <button onClick={() => dispatch({ type: 'setRandom'})}>Random</button>
  37.          <hr/>
  38.          <Dashboard />
  39.       </CountDispatchContext.Provider>
  40.     </CountStateContext.Provider>
  41.   </div>
  42. }
  43.  
  44. export const Dashboard = React.memo(() => {
  45.   console.log('dashboard')
  46.   return <div>
  47.     <Panel1 />
  48.     <Panel2 />
  49.   </div>
  50. })
  51.  
  52. export const Panel1 = () => {
  53.   console.log('panel 1')
  54.   const state = useContext(CountStateContext)
  55.   return <div>
  56.     Panel1 {JSON.stringify(state)}
  57.   </div>
  58. }
  59. /**
  60.  * Not rendered since it's not using CountStateContext
  61.  * @constructor
  62.  */
  63. export const Panel2 = () => {
  64.   console.log('panel 2')
  65.   const dispatch = useContext(CountDispatchContext);
  66.  
  67.   return <div>
  68.     Panel 2: <button onClick={() => dispatch({ type: 'increment'})}>+ (from child)</button>
  69.   </div>
  70. }
  71.  
  72.  
RAW Paste Data