React Stately

3.46.0 · active · verified Tue Apr 21

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.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to use `useListState` to manage selection state for a list of items, including toggling selection and programmatic state manipulation.

import { useListState } from 'react-stately';
import React from 'react';

interface Item {
  id: string;
  name: string;
}

const initialItems: Item[] = [
  { id: '1', name: 'Apple' },
  { id: '2', name: 'Banana' },
  { id: '3', name: 'Orange' }
];

function MyStatefulList() {
  const state = useListState<Item>({
    items: initialItems,
    selectionMode: 'multiple',
    onSelectionChange: (keys) => {
      console.log('Current selected keys:', Array.from(keys));
      // In a real app, you would update your UI based on this state.
      // E.g., render selected items or highlight them.
    },
    getKey: (item) => item.id,
  });

  const toggleItem = (id: string) => {
    if (state.selectionManager.isSelected(id)) {
      state.selectionManager.toggleSelection(id);
    } else {
      state.selectionManager.addSelection(id);
    }
  };

  return (
    <div style={{ padding: '20px', border: '1px solid #ccc', borderRadius: '5px' }}>
      <h3>List State Management Example</h3>
      <p>Click items to toggle selection:</p>
      <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
        {[...state.collection].map((item) => (
          <li
            key={item.key}
            onClick={() => toggleItem(item.key)}
            style={{
              padding: '8px',
              cursor: 'pointer',
              background: state.selectionManager.isSelected(item.key) ? '#e0f7fa' : 'white',
              borderBottom: '1px solid #eee'
            }}
          >
            {item.value?.name} {state.selectionManager.isSelected(item.key) && ' (Selected)'}
          </li>
        ))}
      </ul>
      <p style={{ marginTop: '15px' }}>
        Selected IDs: {Array.from(state.selectionManager.selectedKeys).join(', ') || 'None'}
      </p>
      <button
        onClick={() => state.selectionManager.clearSelection()}
        style={{ marginTop: '10px', padding: '8px 15px', cursor: 'pointer' }}
      >
        Clear Selection
      </button>
      <button
        onClick={() => state.selectionManager.selectAll()}
        style={{ marginTop: '10px', marginLeft: '10px', padding: '8px 15px', cursor: 'pointer' }}
      >
        Select All
      </button>
    </div>
  );
}

export default MyStatefulList;

view raw JSON →