Advertisement
fabiobiondi

React: nested context

Oct 21st, 2020
4,563
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { memo, useContext, useState } from 'react';
  2.  
  3. /**
  4.  * Nested context example
  5.  * UPDATE FROM PREVIOUS EXAMPLE: we use 2 different contexts instead one and they are nested
  6.  * BAD: children components that use inner context is re-rendered
  7.  * when the outer context is updated even if it's not necessary
  8.  */
  9.  
  10. interface Count {
  11.   value: number,
  12. }
  13.  
  14. interface Random {
  15.   value: number | null,
  16. }
  17.  
  18. const CountContext = React.createContext<Count>({ value: 0 });
  19. const RandomContext = React.createContext<Random>({ value: null });
  20.  
  21.  
  22. /**
  23.  * Main Smart Component
  24.  * BAD: always rendered when Context changes since it updates a local state
  25.  */
  26. export default function Demo2BContext() {
  27.   console.log('App: render')
  28.  
  29.   const [count, setCount] = useState<Count>({ value: 0});
  30.   const [random, setRandom] = useState<Random>({ value: 0.5});
  31.  
  32.   return (
  33.     <CountContext.Provider value={count}>
  34.       <RandomContext.Provider value={random}>
  35.         <h1>Demo B: Context</h1>
  36.         <button onClick={() => setCount({ value: count.value + 1})}>+</button>
  37.         <button onClick={() => setCount({ value: count.value - 1})}>-</button>
  38.         <button onClick={() => setRandom({ value: Math.random() })}>Random</button>
  39.         <Dashboard  />
  40.       </RandomContext.Provider>
  41.     </CountContext.Provider>
  42.   );
  43. }
  44.  
  45. // Middle Component
  46. // Never re-rendered because of memoization
  47. const Dashboard = React.memo(() => {
  48.   console.log('dashboard: render')
  49.   return <div>
  50.     <CounterPanel />
  51.     <RandomPanelMemo />
  52.   </div>
  53. })
  54.  
  55. // Child Component
  56. // BAD: Updated when any value of Context change: count / random or another (although memoized)
  57. const CounterPanel = React.memo(() => {
  58.   const state = useContext(CountContext);
  59.  
  60.   console.log('CounterPanel: render')
  61.   return <div>
  62.     Count: {state.value}
  63.   </div>
  64. })
  65.  
  66.  
  67. // Child Component
  68. // BAD: This is re-rendered even if counter is updated and todos is not
  69. function RandomPanel () {
  70.   const state = useContext(RandomContext);
  71.  
  72.   console.log('RandomPanel: render')
  73.   return <div>
  74.     Random Value: {state.value}
  75.   </div>
  76. }
  77.  
  78. const RandomPanelMemo = memo(RandomPanel)
  79.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement