Beta Preview

useFocus

Handles focus events for the immediate target. Focus events on child elements will be ignored.

API

useFocus<Target extends FocusableElement = FocusableElement>(props: <Target>): <Target>

Features

useFocus handles focus interactions for an element. Unlike React's built-in focus events, useFocus does not fire focus events for child elements of the target. This matches DOM behavior where focus events do not bubble. This is similar to the :focus pseudo class in CSS.

To handle focus events on descendants of an element, see useFocusWithin.

Usage

useFocus returns props that you should spread onto the target element:

NameType
focusProps<Target>
Props to spread onto the target element.

useFocus supports the following options and event handlers:

NameType
onFocusChange(isFocused: boolean) => void
Handler that is called when the element's focus status changes.
onBlur(e: FocusEvent<Target>) => void
Handler that is called when the element loses focus.
onFocus(e: FocusEvent<Target>) => void
Handler that is called when the element receives focus.
isDisabledboolean
Whether the focus events should be disabled.

Example

This example shows a simple input element that handles focus events with useFocus and logs them to a list below.

    import React from 'react';
    import {useFocus} from '@react-aria/interactions';
    
    function Example() {
      let [events, setEvents] = React.useState([]);
      let {focusProps} = useFocus({
        onFocus: e => setEvents(
          events => [...events, 'focus']
        ),
        onBlur: e => setEvents(
          events => [...events, 'blur']
        ),
        onFocusChange: isFocused => setEvents(
          events => [...events, `focus change: ${isFocused}`]
        )
      });
    
      return (
        <>
          <label htmlFor="example">Example</label>
          <input
            {...focusProps}
            id="example" />
          <ul
            style={{
              maxHeight: '200px',
              overflow: 'auto'
            }}>
            {events.map((e, i) => <li key={i}>{e}</li>)}
          </ul>
        </>
      );
    }