useReducer exercises

This exercise introduces the useReducer hook; according to the documentation

useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.

Part 1: Include useState in existing useReducer

Continue work on the UseReducerDemo.tsx in repo:

https://github.com/jonatanhallenberg/advanced-react-141114-demo

Remove the state-variable:

const [newTodo, setNewTodo] = useState("");

and include it in the reducer instead.


Part 2: The capabilities of useReducer

Use the counter example from the documentation as a guide.

import { useState, useEffect, useReducer } from "react";

// ...

function Counter() {
  const [state, dispatch] = useReducer(
    // Reducer function
    (state, action) => {
      switch (action.type) {
        // TODO:
        //
        // Return updated state by handling actions:
        //
        // UPDATE: Increments the count by incBy.
        // CHANGE: Change the incBy value.

        default:
          return state;
      }
    },
    // Initial state
    {
      count: 0,
      incBy: 1,
    }
  );

  // TODO:
  //
  // Refactor useEffect callback to dispatch an UPDATE action.

  return (
    <>
      <p>Count: {state.count}</p>
      <input
        type="number"
        value={state.incBy}
        onChange={(e) => {
          const incBy = +e.target.value;

          // TODO:
          //
          // Dispatch a CHANGE action.
        }}
      />
    </>
  );
}

export function App() {
  const [show, setShow] = useState(true);

  return (
    <>
      <button onClick={() => setShow(true)}>Show Counter</button>
      <button onClick={() => setShow(false)}>Hide Counter</button>
      {show && <Counter />}
    </>
  );
}

Part 3: Custom hook - useMyReducer (a bit more advanced)