{"id":15219,"library":"react-stately","title":"React Stately","description":"React Stately is a JavaScript/TypeScript library developed by Adobe, providing highly accessible and robust state management hooks for complex UI components within the React ecosystem. It is a foundational part of the Adobe React Spectrum and React Aria libraries, focusing on managing component behavior and data without dictating visual presentation. This \"headless\" approach allows developers to build custom UIs while leveraging battle-tested accessibility and interaction patterns. As of April 2026, the current stable version is 3.46.0. The library follows a frequent release cadence, often with monthly or bi-monthly updates, reflecting ongoing feature development and improvements, especially in coordination with React Aria Components and React Spectrum S2. Its key differentiators include a strong emphasis on WAI-ARIA standards compliance, complex collection management (lists, grids, trees), and sophisticated interaction handling, making it suitable for enterprise-grade applications requiring high accessibility and performance.","status":"active","version":"3.46.0","language":"javascript","source_language":"en","source_url":"https://github.com/adobe/react-spectrum","tags":["javascript","typescript"],"install":[{"cmd":"npm install react-stately","lang":"bash","label":"npm"},{"cmd":"yarn add react-stately","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-stately","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"React is a peer dependency required for all hooks and components provided by this library.","package":"react","optional":false}],"imports":[{"note":"Primarily consumed as an ESM module. CommonJS `require` should be avoided for modern React projects.","wrong":"const { useListState } = require('react-stately');","symbol":"useListState","correct":"import { useListState } from 'react-stately';"},{"note":"All provided hooks are named exports, not default exports.","wrong":"import useSelectState from 'react-stately';","symbol":"useSelectState","correct":"import { useSelectState } from 'react-stately';"},{"note":"Manages state for a group of checkboxes.","symbol":"useCheckboxGroupState","correct":"import { useCheckboxGroupState } from 'react-stately';"},{"note":"Used for building declarative collections in conjunction with <Item> and <Section> components.","symbol":"CollectionBuilder","correct":"import { CollectionBuilder } from 'react-stately';"},{"note":"Used declaratively within CollectionBuilder or directly in components like <ListBox> to define collection items.","symbol":"Item","correct":"import { Item } from 'react-stately';"}],"quickstart":{"code":"import { useListState } from 'react-stately';\nimport React from 'react';\n\ninterface Item {\n  id: string;\n  name: string;\n}\n\nconst initialItems: Item[] = [\n  { id: '1', name: 'Apple' },\n  { id: '2', name: 'Banana' },\n  { id: '3', name: 'Orange' }\n];\n\nfunction MyStatefulList() {\n  const state = useListState<Item>({\n    items: initialItems,\n    selectionMode: 'multiple',\n    onSelectionChange: (keys) => {\n      console.log('Current selected keys:', Array.from(keys));\n      // In a real app, you would update your UI based on this state.\n      // E.g., render selected items or highlight them.\n    },\n    getKey: (item) => item.id,\n  });\n\n  const toggleItem = (id: string) => {\n    if (state.selectionManager.isSelected(id)) {\n      state.selectionManager.toggleSelection(id);\n    } else {\n      state.selectionManager.addSelection(id);\n    }\n  };\n\n  return (\n    <div style={{ padding: '20px', border: '1px solid #ccc', borderRadius: '5px' }}>\n      <h3>List State Management Example</h3>\n      <p>Click items to toggle selection:</p>\n      <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>\n        {[...state.collection].map((item) => (\n          <li\n            key={item.key}\n            onClick={() => toggleItem(item.key)}\n            style={{\n              padding: '8px',\n              cursor: 'pointer',\n              background: state.selectionManager.isSelected(item.key) ? '#e0f7fa' : 'white',\n              borderBottom: '1px solid #eee'\n            }}\n          >\n            {item.value?.name} {state.selectionManager.isSelected(item.key) && ' (Selected)'}\n          </li>\n        ))}\n      </ul>\n      <p style={{ marginTop: '15px' }}>\n        Selected IDs: {Array.from(state.selectionManager.selectedKeys).join(', ') || 'None'}\n      </p>\n      <button\n        onClick={() => state.selectionManager.clearSelection()}\n        style={{ marginTop: '10px', padding: '8px 15px', cursor: 'pointer' }}\n      >\n        Clear Selection\n      </button>\n      <button\n        onClick={() => state.selectionManager.selectAll()}\n        style={{ marginTop: '10px', marginLeft: '10px', padding: '8px 15px', cursor: 'pointer' }}\n      >\n        Select All\n      </button>\n    </div>\n  );\n}\n\nexport default MyStatefulList;\n","lang":"typescript","description":"Demonstrates how to use `useListState` to manage selection state for a list of items, including toggling selection and programmatic state manipulation."},"warnings":[{"fix":"Consider pairing `react-stately` with `react-aria` for full accessibility and interaction logic, or `@react-spectrum/s2` for pre-built components.","message":"React Stately is a 'headless' state management library, meaning it provides state and logic but no visual UI or accessibility attributes. It is typically used in conjunction with `react-aria` (for accessible DOM properties and interactions) or `@react-spectrum/s2` (for Adobe's Spectrum Design System components). Using React Stately alone requires manual implementation of significant ARIA attributes and event handling for accessibility.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Ensure `getKey` prop is correctly implemented for all items to provide stable, unique keys. Thoroughly test dynamic collection updates and nested structures.","message":"The `CollectionBuilder`, `Item`, and `Section` components/utilities, while powerful for declarative collection definition, can be complex. Incorrect usage, especially with dynamic data or deeply nested structures, can lead to incorrect keys, hydration mismatches, or rendering issues.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Always explicitly define the generic type parameter for hooks like `useListState`, `useSelectState`, etc., based on the shape of your data items.","message":"When using `react-stately` hooks with TypeScript, it is crucial to provide correct generic types (e.g., `useListState<MyItemType>`). Failure to do so can result in `any` types, loss of type safety, or type errors when accessing properties from `state.collection` or item values.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Always use ES module `import` syntax (e.g., `import { useListState } from 'react-stately';`). Ensure your build setup correctly processes ES modules.","message":"The library primarily uses named exports and is designed for ESM environments. While bundlers usually handle CJS compatibility, direct `require()` statements for specific symbols might not work as expected in certain setups or older Node.js versions.","severity":"breaking","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure `useListState` or other `react-stately` hooks are called at the top level of your functional component, not inside loops, conditions, or nested functions.","cause":"`react-stately` hooks, like all React hooks, must be called directly within a React functional component or a custom hook.","error":"Error: Hooks can only be called inside of the body of a function component."},{"fix":"Verify that the `items` array passed to `useListState` is correctly formatted and not `null` or `undefined`. Ensure `getKey` is also provided if items don't have a default `id` or `key` property.","cause":"This typically occurs if the `items` prop was not provided or was provided incorrectly to `useListState` (or similar hooks), leading to an uninitialized or improperly formed collection object.","error":"TypeError: state.collection is not iterable"},{"fix":"Provide a stable and unique `getKey` function in the `useListState` (or similar hook) options, or explicitly set a `key` prop on your rendered elements using `item.key` or a truly unique identifier from `item.value`.","cause":"When rendering items from `state.collection` within a React list, React requires a unique `key` prop for each item to efficiently track changes. This can happen if `getKey` is not specified or returns non-unique values.","error":"Warning: Each child in a list should have a unique \"key\" prop."},{"fix":"Define the generic type for the hook, e.g., `const state = useListState<MyItemType>({ items: ..., ... });`. This ensures `item.value` is correctly typed as `MyItemType`.","cause":"This happens when accessing `item.value` from an item retrieved from `state.collection` without providing the correct generic type to the `useListState` hook.","error":"Property 'value' does not exist on type 'unknown' (or 'any')"}],"ecosystem":"npm"}