Skip to the content.

Module 1: Where state lives · Lesson 1 of 7 · 3 min read

State: decide where a value lives first

Before an agent writes a reducer, classify every value as local, global, server or URL state. That one decision sizes everything after it.

Four homes for a value

The State doc names three kinds of state, and the state-state skill adds a fourth:

  • Local state belongs to one component: an input’s value, or whether a dropdown is open.
  • Global state is shared across unrelated components or routes: the signed-in user, the theme, a cart. This is what the store is for.
  • Server state is data fetched from an API that has to stay in sync, which brings loading, caching and stale copies with it.
  • URL state is shareable and bookmarkable: the page, the filters, the sort order.

The skill’s decision tree is short enough to paste into a prompt. If unrelated components need the value, it is global. Otherwise, if it comes from an API, it is server state. Otherwise, if it should survive a shared link, it goes in the URL. Anything left is local.

What the templates chose

Open templates/chota-react-redux/src/state/ to see those decisions made. rootReducer.js combines three slices: todo, filters and config. The todo slice’s initial state (todo/todo.initial.js) holds todoItems with its lifecycle flags isLoading, isActionLoading, isContentLoading and error. That is server state, stored next to its loading and error flags. The visibility filter gets its own filters slice because the filter buttons and the list both read it. If the filtered view had to survive a refresh or a shared link, the decision tree would send it to the URL instead.

The three mistakes agents make

The doc’s Common Mistakes are what an agent writes when nobody steers it:

  1. Storing derived data. It keeps itemCount beside items and updates both. Compute items.length instead: with a single source of truth, the two can never drift apart.
  2. Mutating state directly. It writes user.age = 31; setUser(user). React and most state libraries detect a change by comparing references, so this update silently disappears.
  3. Putting everything in global state. It adds modal1Open, dropdown1Expanded and inputFocused to the store. Every subscriber now re-renders, and every component becomes harder to reuse.

The second mistake is why the practice question has you clone data at the store’s edge. When data comes from outside, copy it once on the way in, and never keep a reference that other code can still mutate.

Brief an agent with it

Before you ask for a feature, list its values and where each one lives:

State plan for the product list:
- search box text: local (SearchInput)
- signed-in user: global (store, user slice)
- products: server state, with loading and error tracked
- category filter and page: URL search params
Derive counts and totals in selectors; store none of them.

Then review the diff against the skill’s quality gates:

  • No value is stored in two places.
  • Derived data is computed, not stored.
  • Loading and error states are handled.
  • Everything in the store can be serialised.

Encode it, then practise it

Agent Skill: state-state The SKILL.md that encodes State Basics for a coding agent. Install it into your agent, or download it for any Agent-Skills-compatible runtime.
npx skills add grvpanchal/elegant --skill state-state
Download state-state SKILL.md

Practise it

Deep clone a value

Copy nested data without sharing references — including the cycle that makes the naive version hang forever.

coding medium state 30 min Solved

Course contents (7 lessons)

Module 1: Where state lives

  1. State: decide where a value lives first done
  2. Store: one source of truth, one way in done

Module 2: The write path

  1. Actions: describe what happened, not what to set done
  2. Reducer: the only place state changes done
  3. Middleware: the pipeline between dispatch and reducer done

Module 3: The read path and async

  1. Selectors: derive, don't store done
  2. Operations: every request is a lifecycle done