# useToDo & useLocalStorage Hooks

> Refactor the existing ToDo app by moving all task-related logic into a custom hook `useTodo`, and persist tasks in `localStorage` through a separate `useLocalStorage` hook.

- Difficulty: beginner
- Tags: customHook, useEffect, useState
- Estimated time: 15 minutes
- Tests: 6
- Requires subscription: no

## Overview

Refactor the existing ToDo app by moving all task-related logic into a custom hook `useTodo`, and persist tasks in `localStorage` through a separate `useLocalStorage` hook.


## Requirements

- Move the current ToDo logic (state, handlers, etc.) into a custom hook called `useTodo`.
- Implement a `useLocalStorage` hook responsible for synchronizing the ToDo list with `localStorage`.
- The ToDo list must:
  - Load saved tasks from `localStorage` on mount.
  - Save updated tasks to `localStorage` whenever the list changes.
- The `useTodo` hook should expose:
  - The list of tasks.
  - Functions to:
    - Add a task when submitting the form.
    - Delete a task.
    - Toggle a task's completion status, applying a line-through style when completed.
    - Clear completed tasks.
- Show the "Clear complete" button only when there is at least one completed task.


## Notes

- The main goal is to **separate responsibilities**:
  - `useTodo` handles app logic.
  - `useLocalStorage` handles persistence.
- The starter app is already functional: add, toggle, delete and clear all work in `App.tsx`, so the behavior tests already pass. The tests verify **behavior, not implementation** — they don't care whether the logic lives in `App` or in a custom hook.
- The real objective is the **refactor**: extract all task logic into `useTodo` and move persistence into `useLocalStorage` without changing the UI. The persistence test (06) is the only one failing with the starter — it passes once tasks are saved to and loaded from `localStorage`.
- A natural API for `useTodo` is to return the list, a derived `hasCompleted` flag, and the handlers the UI needs:
  ```ts
  return {
    list,
    hasCompleted,
    handleAddTask,
    handleDeleteTask,
    handleCompleteTask,
    handleClearComplete,
  };
  ```
  The exact names are up to you — the tests only check behavior.
- Keep your hooks **pure and reusable** — avoid ToDo-specific logic in `useLocalStorage`.
- When initializing state from `localStorage`, remember to handle missing or malformed data safely.
- The UI code should not change beyond using `useTodo` instead of local state.
- How you manage the input is up to you:
  - **Controlled**: store the input value in state and expose it (value + setter) from `useTodo`.
  - **Uncontrolled**: read the value from the form on submit (e.g. `FormData`) and reset the form. The reference solution does this, so `useTodo` doesn't expose an input setter.


## Tests

01. adds a task when submitting the form
02. toggles task completion and apply line-through when checkbox is clicked
03. deletes a task when delete button is clicked
04. shows only 'Clear complete' button when there is at least one completed task
05. clears completed tasks when 'Clear complete' is clicked
06. persists tasks in localStorage across mounts


