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 is incrementally adoptable. Each component is published as a separate package, so you can try it out in a single component and gradually add more over time. All of these packages are published under the @react-stately scope on npm.

You can install any React Stately package using a package manager like npm or yarn.

yarn add @react-stately/radio

We also offer a single package containing all React Stately hooks. See below for details.

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/radio';

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/radio';

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/radio';

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.

Mono-package#


In addition to individual packages, we also offer a mono-package containing all of the React Stately hooks in a single package. This ensures that all packages use compatible versions and are upgraded together. If you release all components in your component library in a single package, or just want to get started easily without installing a lot of packages, the mono-package may be the way to go. It is available as the react-stately package on npm.

yarn add react-stately

Once installed, all hooks work the same way as the individual packages, but are imported from the react-stately package instead of individual packages.

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

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.