■P238

────────────────
import { useState } from "react";

const useCounter = () => {
  const [count, setCount] = useState(0);

  const increment = () => setCount((prev) => prev + 1);
  const reset = () => setCount(0);

  return { count, increment, reset };
};

const CounterComponent = () => {
  const { count, increment, reset } = useCounter();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
};
────────────────


■P239

────────────────
import { useState } from "react";

const useLocalStorageState = (key, initialValue) => {
  const [state, setState] = useState(() => {
    const storedValue = localStorage.getItem(key);
    return storedValue ? JSON.parse(storedValue) : initialValue;
  });

  const setLocalStorageState = (value) => {
    setState(value);
    localStorage.setItem(key, JSON.stringify(value));
  };

  return [state, setLocalStorageState];
};

const ThemeToggler = () => {
  const [theme, setTheme] = useLocalStorageState("theme", "light");

  return (
    <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
      Toggle Theme
    </button>
  );
};

const App = () => {
  const [theme, setTheme] = useLocalStorageState("theme", "light");

  return (
    <div>
      <p>Current Theme: {theme}</p>
      <ThemeToggler />
    </div>
  );
};

export default App;
────────────────


■P240

hooks.test.js
────────────────
describe("useCounter", () => {
  const { result } = renderHook(() => useCounter());
  const [count] = result.current;

  test("初期値は0", () => {
    expect(count).toEqual(0);
  });

  …省略…
});
────────────────


■P241

────────────────
// 正しい例
function useExampleHook() {
  // ロジック
};

// 間違った例
function exampleHook() {
  // React はこれをフックと認識しない
};
────────────────

────────────────
// 正しい例
function SomeComponent() {
  const data = useExampleHook();
};

// 間違った例
function SomeComponent() {
  if (condition) {
    const data = useExampleHook();
  }
};
────────────────

