Toggle with useState

We start from the most simple example: a toggle.

Think of a checkbox or a light switch. With useState we can represent this as a boolean:

import { useState } from "react";

type Context = boolean;
const initialContext = false;

export default function UseState() {
  // 👇 Single `useState` storing a `boolean`
  const [context, setContext] = useState<Context>(initialContext);
  return (<></>);
}

A boolean toggle is common with checkbox <input>. When the checkbox is clicked, the context will be toggled:

import { useState } from "react";

type Context = boolean;
const initialContext = false;

export default function UseState() {
  const [context, setContext] = useState<Context>(initialContext);
  return (
    <input
      type="checkbox"
      checked={context}
      onChange={() => setContext(!context)}
    />
  );
}

Notice how with useState the state logic is defined directly inside the component. From onChange we explicitly call setContext:

import { useState } from "react";

type Context = boolean;
const initialContext = false;

export default function UseState() {
  const [context, setContext] = useState<Context>(initialContext);
  return (
    <input
      type="checkbox"
      checked={context}
      onChange={() => setContext(!context)}
    />
  );
}

While this strategy makes the code easier for simple use cases, we are going to see later that this is not always the best solution.