React

by Niels Krijger

HTML

<div id="app"></div>

CSS

h1 {
  font-size: 2em;
  font-weight: bold;
}

h2 {
  font-size: 1.5em;
  font-weight: bold;
 
}

.block {
  padding: 1em;
}

React

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    default:
      return state;
  }
}

const initialState = {
    count: 0,
};

const MyContext = React.createContext();


const MyContextProvider = ({ children }) => {
  const [state, dispatch] =  React.useReducer(reducer, initialState);

  return (
    <MyContext.Provider
      value={{ state, dispatch }}
    >
      {children}
    </MyContext.Provider>
  );
};

let component1RenderCount = 0;

const Component1 = () => {
  component1RenderCount += 1;
  const { dispatch } = React.useContext(MyContext);
  
  return (
  	<div className="block">
      <button type="input" onClick={() => dispatch({ type: 'increment' }) }>Button 1</button>
      &nbsp; Component1 renders: {component1RenderCount}
    </div>
  );
}

let component2RenderCount = 0;

const Component2 = () => {
  component2RenderCount += 1;
  const { dispatch } = React.useContext(MyContext);
  
  return (
  	<div className="block">
      <button type="input" onClick={() => dispatch({ type: 'increment' }) }>Button 2</button>
      &nbsp; Component2 renders: {component2RenderCount}
    </div>
  );
}

const StateCount = () => {
  const { state } = React.useContext(MyContext);
  
  return (
  	<h2>Counter: {state.count}</h2>
  )
};

const App = props => {
	return (
	  <MyContextProvider>
      <h1>Subscribing to context state</h1>
      <StateCount />
      <Component1 />
      <Component2 />
    </MyContextProvider>
  );
};


// -- Split it in two


const StateContext = React.createContext();
const DispatchContext = React.createContext();

const MyComplexContextProvider = ({ children }) => {
  const [state, dispatch] =  React.useReducer(reducer, initialState);

  return (
    <DispatchContext.Provider value={dispatch}>
      <StateContext.Provider value={state}>
        {children}
      </StateContext.Provider>
    </DispatchContext.Provider>
  );
};


let component3RenderCount = 0;

const...