useFocus

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

installyarn add @react-aria/interactions
version3.5.0
usageimport {useFocus} from '@react-aria/interactions'

API#


useFocus( (props: FocusProps )): FocusResult

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:

NameTypeDescription
focusPropsHTMLAttributes<HTMLElement>Props to spread onto the target element.

useFocus supports the following event handlers:

NameTypeDescription
onFocus( (e: FocusEvent )) => voidHandler that is called when the element receives focus.
onBlur( (e: FocusEvent )) => voidHandler that is called when the element loses focus.
onFocusChange( (isFocused: boolean )) => voidHandler that is called when the element's focus status changes.

Example#


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

NOTE: for more advanced text field functionality, see useTextField.

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 (
    <>
      <input {...focusProps} aria-label="Example" placeholder="Focus me!" />
      <ul
        style={{
          maxHeight: '200px',
          overflow: 'auto'
        }}>
        {events.map((e, i) => (
          <li key={i}>{e}</li>
        ))}
      </ul>
    </>
  );
}
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 (
    <>
      <input
        {...focusProps}
        aria-label="Example"
        placeholder="Focus me!"
      />
      <ul
        style={{
          maxHeight: '200px',
          overflow: 'auto'
        }}>
        {events.map((e, i) => (
          <li key={i}>{e}</li>
        ))}
      </ul>
    </>
  );
}
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 (
    <>
      <input
        {...focusProps}
        aria-label="Example"
        placeholder="Focus me!"
      />
      <ul
        style={{
          maxHeight:
            '200px',
          overflow:
            'auto'
        }}>
        {events.map(
          (e, i) => (
            <li key={i}>
              {e}
            </li>
          )
        )}
      </ul>
    </>
  );
}