{"id":"03964817-16dd-4fb4-9649-009bc4023351","shortId":"c2vcBX","kind":"skill","title":"react-state-management","tagline":"Master modern React state management with Redux Toolkit, Zustand, Jotai, and React Query. Use when setting up global state, managing server state, or choosing between state management solutions.","description":"# React State Management\n\nComprehensive guide to modern React state management patterns, from local component state to global stores and server state synchronization.\n\n## Do not use this skill when\n\n- The task is unrelated to react state management\n- You need a different domain or tool outside this scope\n\n## Instructions\n\n- Clarify goals, constraints, and required inputs.\n- Apply relevant best practices and validate outcomes.\n- Provide actionable steps and verification.\n- If detailed examples are required, open `resources/implementation-playbook.md`.\n\n## Use this skill when\n\n- Setting up global state management in a React app\n- Choosing between Redux Toolkit, Zustand, or Jotai\n- Managing server state with React Query or SWR\n- Implementing optimistic updates\n- Debugging state-related issues\n- Migrating from legacy Redux to modern patterns\n\n## Core Concepts\n\n### 1. State Categories\n\n| Type | Description | Solutions |\n|------|-------------|-----------|\n| **Local State** | Component-specific, UI state | useState, useReducer |\n| **Global State** | Shared across components | Redux Toolkit, Zustand, Jotai |\n| **Server State** | Remote data, caching | React Query, SWR, RTK Query |\n| **URL State** | Route parameters, search | React Router, nuqs |\n| **Form State** | Input values, validation | React Hook Form, Formik |\n\n### 2. Selection Criteria\n\n```\nSmall app, simple state → Zustand or Jotai\nLarge app, complex state → Redux Toolkit\nHeavy server interaction → React Query + light client state\nAtomic/granular updates → Jotai\n```\n\n## Quick Start\n\n### Zustand (Simplest)\n\n```typescript\n// store/useStore.ts\nimport { create } from 'zustand'\nimport { devtools, persist } from 'zustand/middleware'\n\ninterface AppState {\n  user: User | null\n  theme: 'light' | 'dark'\n  setUser: (user: User | null) => void\n  toggleTheme: () => void\n}\n\nexport const useStore = create<AppState>()(\n  devtools(\n    persist(\n      (set) => ({\n        user: null,\n        theme: 'light',\n        setUser: (user) => set({ user }),\n        toggleTheme: () => set((state) => ({\n          theme: state.theme === 'light' ? 'dark' : 'light'\n        })),\n      }),\n      { name: 'app-storage' }\n    )\n  )\n)\n\n// Usage in component\nfunction Header() {\n  const { user, theme, toggleTheme } = useStore()\n  return (\n    <header className={theme}>\n      {user?.name}\n      <button onClick={toggleTheme}>Toggle Theme</button>\n    </header>\n  )\n}\n```\n\n## Patterns\n\n### Pattern 1: Redux Toolkit with TypeScript\n\n```typescript\n// store/index.ts\nimport { configureStore } from '@reduxjs/toolkit'\nimport { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'\nimport userReducer from './slices/userSlice'\nimport cartReducer from './slices/cartSlice'\n\nexport const store = configureStore({\n  reducer: {\n    user: userReducer,\n    cart: cartReducer,\n  },\n  middleware: (getDefaultMiddleware) =>\n    getDefaultMiddleware({\n      serializableCheck: {\n        ignoredActions: ['persist/PERSIST'],\n      },\n    }),\n})\n\nexport type RootState = ReturnType<typeof store.getState>\nexport type AppDispatch = typeof store.dispatch\n\n// Typed hooks\nexport const useAppDispatch: () => AppDispatch = useDispatch\nexport const useAppSelector: TypedUseSelectorHook<RootState> = useSelector\n```\n\n```typescript\n// store/slices/userSlice.ts\nimport { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'\n\ninterface User {\n  id: string\n  email: string\n  name: string\n}\n\ninterface UserState {\n  current: User | null\n  status: 'idle' | 'loading' | 'succeeded' | 'failed'\n  error: string | null\n}\n\nconst initialState: UserState = {\n  current: null,\n  status: 'idle',\n  error: null,\n}\n\nexport const fetchUser = createAsyncThunk(\n  'user/fetchUser',\n  async (userId: string, { rejectWithValue }) => {\n    try {\n      const response = await fetch(`/api/users/${userId}`)\n      if (!response.ok) throw new Error('Failed to fetch user')\n      return await response.json()\n    } catch (error) {\n      return rejectWithValue((error as Error).message)\n    }\n  }\n)\n\nconst userSlice = createSlice({\n  name: 'user',\n  initialState,\n  reducers: {\n    setUser: (state, action: PayloadAction<User>) => {\n      state.current = action.payload\n      state.status = 'succeeded'\n    },\n    clearUser: (state) => {\n      state.current = null\n      state.status = 'idle'\n    },\n  },\n  extraReducers: (builder) => {\n    builder\n      .addCase(fetchUser.pending, (state) => {\n        state.status = 'loading'\n        state.error = null\n      })\n      .addCase(fetchUser.fulfilled, (state, action) => {\n        state.status = 'succeeded'\n        state.current = action.payload\n      })\n      .addCase(fetchUser.rejected, (state, action) => {\n        state.status = 'failed'\n        state.error = action.payload as string\n      })\n  },\n})\n\nexport const { setUser, clearUser } = userSlice.actions\nexport default userSlice.reducer\n```\n\n### Pattern 2: Zustand with Slices (Scalable)\n\n```typescript\n// store/slices/createUserSlice.ts\nimport { StateCreator } from 'zustand'\n\nexport interface UserSlice {\n  user: User | null\n  isAuthenticated: boolean\n  login: (credentials: Credentials) => Promise<void>\n  logout: () => void\n}\n\nexport const createUserSlice: StateCreator<\n  UserSlice & CartSlice, // Combined store type\n  [],\n  [],\n  UserSlice\n> = (set, get) => ({\n  user: null,\n  isAuthenticated: false,\n  login: async (credentials) => {\n    const user = await authApi.login(credentials)\n    set({ user, isAuthenticated: true })\n  },\n  logout: () => {\n    set({ user: null, isAuthenticated: false })\n    // Can access other slices\n    // get().clearCart()\n  },\n})\n\n// store/index.ts\nimport { create } from 'zustand'\nimport { createUserSlice, UserSlice } from './slices/createUserSlice'\nimport { createCartSlice, CartSlice } from './slices/createCartSlice'\n\ntype StoreState = UserSlice & CartSlice\n\nexport const useStore = create<StoreState>()((...args) => ({\n  ...createUserSlice(...args),\n  ...createCartSlice(...args),\n}))\n\n// Selective subscriptions (prevents unnecessary re-renders)\nexport const useUser = () => useStore((state) => state.user)\nexport const useCart = () => useStore((state) => state.cart)\n```\n\n### Pattern 3: Jotai for Atomic State\n\n```typescript\n// atoms/userAtoms.ts\nimport { atom } from 'jotai'\nimport { atomWithStorage } from 'jotai/utils'\n\n// Basic atom\nexport const userAtom = atom<User | null>(null)\n\n// Derived atom (computed)\nexport const isAuthenticatedAtom = atom((get) => get(userAtom) !== null)\n\n// Atom with localStorage persistence\nexport const themeAtom = atomWithStorage<'light' | 'dark'>('theme', 'light')\n\n// Async atom\nexport const userProfileAtom = atom(async (get) => {\n  const user = get(userAtom)\n  if (!user) return null\n  const response = await fetch(`/api/users/${user.id}/profile`)\n  return response.json()\n})\n\n// Write-only atom (action)\nexport const logoutAtom = atom(null, (get, set) => {\n  set(userAtom, null)\n  set(cartAtom, [])\n  localStorage.removeItem('token')\n})\n\n// Usage\nfunction Profile() {\n  const [user] = useAtom(userAtom)\n  const [, logout] = useAtom(logoutAtom)\n  const [profile] = useAtom(userProfileAtom) // Suspense-enabled\n\n  return (\n    <Suspense fallback={<Skeleton />}>\n      <ProfileContent profile={profile} onLogout={logout} />\n    </Suspense>\n  )\n}\n```\n\n### Pattern 4: React Query for Server State\n\n```typescript\n// hooks/useUsers.ts\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\n\n// Query keys factory\nexport const userKeys = {\n  all: ['users'] as const,\n  lists: () => [...userKeys.all, 'list'] as const,\n  list: (filters: UserFilters) => [...userKeys.lists(), filters] as const,\n  details: () => [...userKeys.all, 'detail'] as const,\n  detail: (id: string) => [...userKeys.details(), id] as const,\n}\n\n// Fetch hook\nexport function useUsers(filters: UserFilters) {\n  return useQuery({\n    queryKey: userKeys.list(filters),\n    queryFn: () => fetchUsers(filters),\n    staleTime: 5 * 60 * 1000, // 5 minutes\n    gcTime: 30 * 60 * 1000, // 30 minutes (formerly cacheTime)\n  })\n}\n\n// Single user hook\nexport function useUser(id: string) {\n  return useQuery({\n    queryKey: userKeys.detail(id),\n    queryFn: () => fetchUser(id),\n    enabled: !!id, // Don't fetch if no id\n  })\n}\n\n// Mutation with optimistic update\nexport function useUpdateUser() {\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: updateUser,\n    onMutate: async (newUser) => {\n      // Cancel outgoing refetches\n      await queryClient.cancelQueries({ queryKey: userKeys.detail(newUser.id) })\n\n      // Snapshot previous value\n      const previousUser = queryClient.getQueryData(userKeys.detail(newUser.id))\n\n      // Optimistically update\n      queryClient.setQueryData(userKeys.detail(newUser.id), newUser)\n\n      return { previousUser }\n    },\n    onError: (err, newUser, context) => {\n      // Rollback on error\n      queryClient.setQueryData(\n        userKeys.detail(newUser.id),\n        context?.previousUser\n      )\n    },\n    onSettled: (data, error, variables) => {\n      // Refetch after mutation\n      queryClient.invalidateQueries({ queryKey: userKeys.detail(variables.id) })\n    },\n  })\n}\n```\n\n### Pattern 5: Combining Client + Server State\n\n```typescript\n// Zustand for client state\nconst useUIStore = create<UIState>((set) => ({\n  sidebarOpen: true,\n  modal: null,\n  toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),\n  openModal: (modal) => set({ modal }),\n  closeModal: () => set({ modal: null }),\n}))\n\n// React Query for server state\nfunction Dashboard() {\n  const { sidebarOpen, toggleSidebar } = useUIStore()\n  const { data: users, isLoading } = useUsers({ active: true })\n  const { data: stats } = useStats()\n\n  if (isLoading) return <DashboardSkeleton />\n\n  return (\n    <div className={sidebarOpen ? 'with-sidebar' : ''}>\n      <Sidebar open={sidebarOpen} onToggle={toggleSidebar} />\n      <main>\n        <StatsCards stats={stats} />\n        <UserTable users={users} />\n      </main>\n    </div>\n  )\n}\n```\n\n## Best Practices\n\n### Do's\n- **Colocate state** - Keep state as close to where it's used as possible\n- **Use selectors** - Prevent unnecessary re-renders with selective subscriptions\n- **Normalize data** - Flatten nested structures for easier updates\n- **Type everything** - Full TypeScript coverage prevents runtime errors\n- **Separate concerns** - Server state (React Query) vs client state (Zustand)\n\n### Don'ts\n- **Don't over-globalize** - Not everything needs to be in global state\n- **Don't duplicate server state** - Let React Query manage it\n- **Don't mutate directly** - Always use immutable updates\n- **Don't store derived data** - Compute it instead\n- **Don't mix paradigms** - Pick one primary solution per category\n\n## Migration Guides\n\n### From Legacy Redux to RTK\n\n```typescript\n// Before (legacy Redux)\nconst ADD_TODO = 'ADD_TODO'\nconst addTodo = (text) => ({ type: ADD_TODO, payload: text })\nfunction todosReducer(state = [], action) {\n  switch (action.type) {\n    case ADD_TODO:\n      return [...state, { text: action.payload, completed: false }]\n    default:\n      return state\n  }\n}\n\n// After (Redux Toolkit)\nconst todosSlice = createSlice({\n  name: 'todos',\n  initialState: [],\n  reducers: {\n    addTodo: (state, action: PayloadAction<string>) => {\n      // Immer allows \"mutations\"\n      state.push({ text: action.payload, completed: false })\n    },\n  },\n})\n```\n\n## Resources\n\n- [Redux Toolkit Documentation](https://redux-toolkit.js.org/)\n- [Zustand GitHub](https://github.com/pmndrs/zustand)\n- [Jotai Documentation](https://jotai.org/)\n- [TanStack Query](https://tanstack.com/query)\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["react","state","management","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding"],"capabilities":["skill","source-sickn33","skill-react-state-management","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/react-state-management","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34583 github stars · SKILL.md body (11,918 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T18:52:06.840Z","embedding":null,"createdAt":"2026-04-18T21:43:22.657Z","updatedAt":"2026-04-22T18:52:06.840Z","lastSeenAt":"2026-04-22T18:52:06.840Z","tsv":"'/)':1148,1158 '/api/users':423,683 '/pmndrs/zustand)':1153 '/profile':685 '/query)':1163 '/slices/cartslice':334 '/slices/createcartslice':582 '/slices/createuserslice':577 '/slices/userslice':330 '1':150,308 '1000':800,806 '2':201,503 '3':616 '30':804,807 '4':734 '5':798,801,900 '60':799,805 'access':563 'across':168 'action':94,454,479,487,692,1105,1132 'action.payload':457,483,491,1114,1139 'action.type':1107 'activ':947 'add':1090,1092,1098,1109 'addcas':469,476,484 'addtodo':1095,1130 'allow':1135 'alway':1056 'app':117,205,212,283 'app-storag':282 'appdispatch':356,364 'appli':86 'appstat':244 'arg':591,593,595 'ask':1197 'async':414,545,663,669,850 'atom':619,624,632,636,641,646,651,664,668,691,696 'atomic/granular':225 'atoms/useratoms.ts':622 'atomwithstorag':628,658 'authapi.login':550 'await':421,435,549,681,855 'basic':631 'best':88,974 'boolean':521 'boundari':1205 'builder':467,468 'button':301 'cach':178 'cachetim':810 'cancel':852 'cart':342 'cartatom':704 'cartreduc':332,343 'cartslic':533,580,586 'case':1108 'catch':437 'categori':152,1077 'choos':28,118 'clarif':1199 'clarifi':80 'classnam':297,958 'clear':1172 'clearcart':567 'clearus':460,497 'client':223,902,908,1024 'close':983 'closemod':927 'coloc':978 'combin':534,901 'complet':1115,1140 'complex':213 'compon':46,159,169,287 'component-specif':158 'comprehens':36 'comput':642,1065 'concept':149 'concern':1018 'configurestor':316,338 'const':259,290,336,362,367,400,410,419,445,495,529,547,588,604,610,634,644,656,666,671,679,694,710,714,718,752,757,762,769,774,781,842,863,910,938,942,949,1089,1094,1123 'constraint':82 'context':879,886 'core':148 'coverag':1013 'creat':235,261,570,590,912 'createasyncthunk':375,412 'createcartslic':579,594 'createslic':374,447,1125 'createuserslic':530,574,592 'credenti':523,524,546,551 'criteria':203,1208 'current':389,403 'dark':250,279,660 'dashboard':937 'data':177,889,943,950,1002,1064 'debug':136 'default':500,1117 'deriv':640,1063 'describ':1176 'descript':154 'detail':99,770,772,775 'devtool':239,262 'differ':72 'direct':1055 'div':957 'document':1145,1155 'domain':73 'duplic':1044 'easier':1007 'email':383 'enabl':724,827 'environ':1188 'environment-specif':1187 'err':877 'error':397,407,429,438,441,443,882,890,1016 'everyth':1010,1035 'exampl':100 'expert':1193 'export':258,335,350,354,361,366,409,494,499,514,528,587,603,609,633,643,655,665,693,751,784,814,839 'extrareduc':466 'factori':750 'fail':396,430,489 'fallback':727 'fals':543,561,1116,1141 'fetch':422,432,682,782,831 'fetchus':411,795,825 'fetchuser.fulfilled':477 'fetchuser.pending':470 'fetchuser.rejected':485 'filter':764,767,787,793,796 'flatten':1003 'form':192,199 'former':809 'formik':200 'full':1011 'function':288,708,785,815,840,936,1102 'gctime':803 'get':539,566,647,648,670,673,698 'getdefaultmiddlewar':345,346 'github':1150 'github.com':1152 'github.com/pmndrs/zustand)':1151 'global':22,49,111,165,1033,1040 'goal':81 'guid':37,1079 'header':289,296 'heavi':217 'hook':198,360,783,813 'hooks/useusers.ts':741 'id':381,776,779,817,823,826,828,834 'idl':393,406,465 'ignoredact':348 'immer':1134 'immut':1058 'implement':133 'import':234,238,315,319,327,331,373,510,569,573,578,623,627,742 'initialst':401,450,1128 'input':85,194,1202 'instead':1067 'instruct':79 'interact':219 'interfac':243,379,387,515 'isauthent':520,542,554,560 'isauthenticatedatom':645 'isload':945,954 'issu':140 'jotai':14,124,173,210,227,617,626,1154 'jotai.org':1157 'jotai.org/)':1156 'jotai/utils':630 'keep':980 'key':749 'larg':211 'legaci':143,1081,1087 'let':1047 'light':222,249,268,278,280,659,662 'limit':1164 'list':758,760,763 'load':394,473 'local':45,156 'localstorag':653 'localstorage.removeitem':705 'login':522,544 'logout':526,556,715,732 'logoutatom':695,717 'manag':4,9,24,31,35,42,68,113,125,1050 'master':5 'match':1173 'messag':444 'middlewar':344 'migrat':141,1078 'minut':802,808 'miss':1210 'mix':1070 'modal':916,924,926,929 'modern':6,39,146 'mutat':835,894,1054,1136 'mutationfn':847 'name':281,300,385,448,1126 'need':70,1036 'nest':1004 'new':428 'newus':851,873,878 'newuser.id':859,867,872,885 'normal':1001 'null':247,254,266,391,399,404,408,463,475,519,541,559,638,639,650,678,697,702,917,930 'nuq':191 'onclick':302 'one':1073 'onerror':876 'onlogout':731 'onmut':849 'onsettl':888 'ontoggl':966 'open':103,964 'openmod':923 'optimist':134,837,868 'outcom':92 'outgo':853 'output':1182 'outsid':76 'over-glob':1031 'paradigm':1071 'paramet':187 'pattern':43,147,306,307,502,615,733,899 'payload':1100 'payloadact':376,455,1133 'per':1076 'permiss':1203 'persist':240,263,654 'persist/persist':349 'pick':1072 'possibl':990 'practic':89,975 'prevent':598,993,1014 'previous':861 'previousus':864,875,887 'primari':1074 'profil':709,719,729,730 'profilecont':728 'promis':525 'provid':93 'queri':17,130,180,183,221,736,748,932,1022,1049,1160 'querycli':843 'queryclient.cancelqueries':856 'queryclient.getquerydata':865 'queryclient.invalidatequeries':895 'queryclient.setquerydata':870,883 'queryfn':794,824 'querykey':791,821,857,896 'quick':228 're':601,996 're-rend':600,995 'react':2,7,16,33,40,66,116,129,179,189,197,220,325,735,931,1021,1048 'react-redux':324 'react-state-manag':1 'reduc':339,451,1129 'redux':11,120,144,170,215,309,326,1082,1088,1121,1143 'redux-toolkit.js.org':1147 'redux-toolkit.js.org/)':1146 'reduxjs/toolkit':318,378 'refetch':854,892 'rejectwithvalu':417,440 'relat':139 'relev':87 'remot':176 'render':602,997 'requir':84,102,1201 'resourc':1142 'resources/implementation-playbook.md':104 'respons':420,680 'response.json':436,687 'response.ok':426 'return':295,434,439,677,686,725,789,819,845,874,955,956,1111,1118 'returntyp':353 'review':1194 'rollback':880 'rootstat':352 'rout':186 'router':190 'rtk':182,1084 'runtim':1015 's.sidebaropen':922 'safeti':1204 'scalabl':507 'scope':78,1175 'search':188 'select':202,596,999 'selector':992 'separ':1017 'serializablecheck':347 'server':25,52,126,174,218,738,903,934,1019,1045 'set':20,109,264,271,274,538,552,557,699,700,703,913,919,925,928 'setus':251,269,452,496 'share':167 'sidebar':962,963 'sidebaropen':914,921,939,959,965 'simpl':206 'simplest':231 'singl':811 'skill':59,107,1167 'skill-react-state-management' 'slice':506,565 'small':204 'snapshot':860 'solut':32,155,1075 'source-sickn33' 'specif':160,1189 'staletim':797 'start':229 'stat':951,969,970 'state':3,8,23,26,30,34,41,47,53,67,112,127,138,151,157,162,166,175,185,193,207,214,224,275,453,461,471,478,486,607,613,620,739,904,909,935,979,981,1020,1025,1041,1046,1104,1112,1119,1131 'state-rel':137 'state.cart':614 'state.current':456,462,482 'state.error':474,490 'state.push':1137 'state.status':458,464,472,480,488 'state.theme':277 'state.user':608 'statecr':511,531 'statscard':968 'status':392,405 'step':95 'stop':1195 'storag':284 'store':50,337,535,1062 'store.dispatch':358 'store/index.ts':314,568 'store/slices/createuserslice.ts':509 'store/slices/userslice.ts':372 'store/usestore.ts':233 'storest':584 'string':382,384,386,398,416,493,777,818 'structur':1005 'subscript':597,1000 'substitut':1185 'succeed':395,459,481 'success':1207 'suspens':723,726 'suspense-en':722 'switch':1106 'swr':132,181 'synchron':54 'tanstack':1159 'tanstack.com':1162 'tanstack.com/query)':1161 'tanstack/react-query':747 'task':62,1171 'test':1191 'text':1096,1101,1113,1138 'theme':248,267,276,292,298,305,661 'themeatom':657 'throw':427 'todo':1091,1093,1099,1110,1127 'todosreduc':1103 'todosslic':1124 'toggl':304 'togglesidebar':918,940,967 'togglethem':256,273,293,303 'token':706 'tool':75 'toolkit':12,121,171,216,310,1122,1144 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'treat':1180 'tri':418 'true':555,915,948 'ts':1028 'type':153,351,355,359,536,583,1009,1097 'typeduseselectorhook':320,369 'typeof':357 'typescript':232,312,313,371,508,621,740,905,1012,1085 'ui':161 'unnecessari':599,994 'unrel':64 'updat':135,226,838,869,1008,1059 'updateus':848 'url':184 'usag':285,707 'use':18,57,105,988,991,1057,1165 'useappdispatch':363 'useappselector':368 'useatom':712,716,720 'usecart':611 'usedispatch':321,365 'usemut':744,846 'usequeri':743,790,820 'usequerycli':745,844 'user':245,246,252,253,265,270,272,291,299,340,380,390,433,449,517,518,540,548,553,558,637,672,676,711,755,812,944,972,973 'user.id':684 'user/fetchuser':413 'useratom':635,649,674,701,713 'usereduc':164 'userfilt':765,788 'userid':415,424 'userkey':753 'userkeys.all':759,771 'userkeys.detail':822,858,866,871,884,897 'userkeys.details':778 'userkeys.list':792 'userkeys.lists':766 'userprofileatom':667,721 'userreduc':328,341 'userslic':446,516,532,537,575,585 'userslice.actions':498 'userslice.reducer':501 'userst':388,402 'usert':971 'useselector':322,370 'usest':163 'usestat':952 'usestor':260,294,589,606,612 'useuistor':911,941 'useupdateus':841 'useus':605,786,816,946 'valid':91,196,1190 'valu':195,862 'variabl':891 'variables.id':898 'verif':97 'void':255,257,527 'vs':1023 'with-sidebar':960 'write':689 'write-on':688 'zustand':13,122,172,208,230,237,504,513,572,906,1026,1149 'zustand/middleware':242","prices":[{"id":"862cc1a1-db28-4798-98ae-445576a616c6","listingId":"03964817-16dd-4fb4-9649-009bc4023351","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:43:22.657Z"}],"sources":[{"listingId":"03964817-16dd-4fb4-9649-009bc4023351","source":"github","sourceId":"sickn33/antigravity-awesome-skills/react-state-management","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/react-state-management","isPrimary":false,"firstSeenAt":"2026-04-18T21:43:22.657Z","lastSeenAt":"2026-04-22T18:52:06.840Z"}],"details":{"listingId":"03964817-16dd-4fb4-9649-009bc4023351","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"react-state-management","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34583,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"db276b23c62bd8382118c5bf3d1ed17a55162135","skill_md_path":"skills/react-state-management/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/react-state-management"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"react-state-management","description":"Master modern React state management with Redux Toolkit, Zustand, Jotai, and React Query. Use when setting up global state, managing server state, or choosing between state management solutions."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/react-state-management"},"updatedAt":"2026-04-22T18:52:06.840Z"}}