Getting Started

This page describes how to get started building your own component library with React Stately.

What is React Stately?#


React Stately is library of React Hooks that provides cross-platform state management for your design system. It provides the foundation and core logic for your component library, and implements state management for many common components. It returns an interface for reading and updating component state, with methods that implement much of the core logic for the component.

React Stately is designed to be cross-platform, and could work on the web, react-native, or any other platform. On the web, it can be paired with React Aria, which provides behavior, accessibility, and user interactions for many components, while React Stately provides state management.

Installation#


React Stately can be installed using a package manager like npm or yarn.

yarn add react-stately

If you prefer, you can also use our hooks from individually versioned packages. This allows you to only install the hooks you use, or more granularly manage their versions. The individual packages are published under the @react-stately scope on npm. For example:

yarn add @react-stately/radio

Once installed, hooks can be used from the monopackage or individual packages the same way.

// Monopackage
import {useRadioGroupState} from 'react-stately';
// Monopackage
import {useRadioGroupState} from 'react-stately';
// Monopackage
import {useRadioGroupState} from 'react-stately';
// Individual packages
import {useRadioGroupState} from '@react-stately/radio';
// Individual packages
import {useRadioGroupState} from '@react-stately/radio';
// Individual packages
import {useRadioGroupState} from '@react-stately/radio';

Building a component#


This example shows a very simple radio group component built with the useRadioGroupState hook to manage state. It generates a name for each input in the group so the browser associates them, and manages the selection state. The example shows uncontrolled behavior using the defaultValue prop, and useRadioGroupState handles firing the onChange event with the new selected value.

import {useRadioGroupState} from 'react-stately';

function RadioGroup(props) {
  let state = useRadioGroupState(props);

  return (
    <>
      <label>
        <input
          type="radio"
          name={state.name}
          checked={state.selectedValue === 'dogs'}
          onChange={() => state.setSelectedValue('dogs')}
        />
        Dogs
      </label>
      <label>
        <input
          type="radio"
          name={state.name}
          checked={state.selectedValue === 'cats'}
          onChange={() => state.setSelectedValue('cats')}
        />
        Cats
      </label>
    </>
  );
}

<RadioGroup
  defaultValue="dogs"
  onChange={(value) => alert(`Selected ${value}`)}
/>
import {useRadioGroupState} from 'react-stately';

function RadioGroup(props) {
  let state = useRadioGroupState(props);

  return (
    <>
      <label>
        <input
          type="radio"
          name={state.name}
          checked={state.selectedValue === 'dogs'}
          onChange={() => state.setSelectedValue('dogs')}
        />
        Dogs
      </label>
      <label>
        <input
          type="radio"
          name={state.name}
          checked={state.selectedValue === 'cats'}
          onChange={() => state.setSelectedValue('cats')}
        />
        Cats
      </label>
    </>
  );
}

<RadioGroup
  defaultValue="dogs"
  onChange={(value) => alert(`Selected ${value}`)}
/>
import {useRadioGroupState} from 'react-stately';

function RadioGroup(
  props
) {
  let state =
    useRadioGroupState(
      props
    );

  return (
    <>
      <label>
        <input
          type="radio"
          name={state
            .name}
          checked={state
            .selectedValue ===
            'dogs'}
          onChange={() =>
            state
              .setSelectedValue(
                'dogs'
              )}
        />
        Dogs
      </label>
      <label>
        <input
          type="radio"
          name={state
            .name}
          checked={state
            .selectedValue ===
            'cats'}
          onChange={() =>
            state
              .setSelectedValue(
                'cats'
              )}
        />
        Cats
      </label>
    </>
  );
}

<RadioGroup
  defaultValue="dogs"
  onChange={(value) =>
    alert(
      `Selected ${value}`
    )}
/>

If you're using React Stately on the web, see useRadioGroup in React Aria to help handle more of this behavior and accessibility for you. To see an example of how React Stately manages more complex state, see useSelectState.

Next steps#


Now that you understand how to use the hooks in React Stately to build your own components, you can read the documentation for the individual hooks to understand them in detail. We also have high level documentation about more complex topics like collections and selection.

For more examples of using React Stately, also check out the docs for React Aria, which is a library of hooks that implement behavior and accessibility for the web on top of React Stately. For a complete example of a full component library built with React Stately and React Aria, also check out React Spectrum. The source code is a good example of how the React Stately and React Aria hooks are used in many real-world components.