0

I tried the sample code of useReducer:

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  // ...

and instantiated 3 Counters in the App. Sample on: https://codesandbox.io/s/serene-morse-c017r

So it seems the state is local to each Counter component, and is not the "single source of truth" like on Redux? If the App wants to get the value of all counters, or one Counter wants to get the value of another Counter, how would that be done?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740

1 Answers1

1

I made changes in your codesandbox and used context to make your counter as single source of truth like redux.

import React from "react";
const CountStateContext = React.createContext();
const CountDispatchContext = React.createContext();
function countReducer(state, action) {
  switch (action.type) {
    case "increment": {
      return { count: state.count + 1 };
    }
    case "decrement": {
      return { count: state.count - 1 };
    }
    default: {
      throw new Error(`Unhandled action type: ${action.type}`);
    }
  }
}
function CountProvider({ children }) {
  const [state, dispatch] = React.useReducer(countReducer, { count: 0 });
  return (
    <CountStateContext.Provider value={state}>
      <CountDispatchContext.Provider value={dispatch}>
        {children}
      </CountDispatchContext.Provider>
    </CountStateContext.Provider>
  );
}
function useCountState() {
  const context = React.useContext(CountStateContext);
  if (context === undefined) {
    throw new Error("useCountState must be used within a CountProvider");
  }
  return context;
}
function useCountDispatch() {
  const context = React.useContext(CountDispatchContext);
  if (context === undefined) {
    throw new Error("useCountDispatch must be used within a CountProvider");
  }
  return context;
}
export { CountProvider, useCountState, useCountDispatch };

https://codesandbox.io/s/modern-wildflower-ihvjj

Amit Chauhan
  • 6,151
  • 2
  • 24
  • 37
  • oh, now, we do want to keep the count for Noodle and Drink independent... so even thought we want "single source of truth", we want to keep the count independent of each other... and want App to be able to access them, and want each counter be able to access other counts... does that involve making 6 actions, and a lot of repeated code? – nonopolarity Feb 14 '20 at 09:37
  • I have updated same codesandbox with you can pass name to get and set counter value. – Amit Chauhan Feb 14 '20 at 09:51
  • so it looks like when the Component is written, it has to be ready for multiple counters and know how to handle it. We can't just write a Counter component that is standalone that doesn't need to worry it has to have a `name`, and use something like `` and be done with it – nonopolarity Feb 14 '20 at 11:28
  • the original concern of using MVC was not to write a large amount of imperative code... but with React it looks like simple things are done with a large amount of code – nonopolarity Feb 16 '20 at 22:23