heroui-inc/heroui · error · Error
useCalendarOrRangeState must be used within a <Calendar> or
Error message
useCalendarOrRangeState must be used within a <Calendar> or <RangeCalendar> component.
What it means
useCalendarOrRangeState is an internal-ish hook used by CalendarYearPicker parts. It reads both the CalendarStateContext and RangeCalendarStateContext; if neither provider is found (i.e., the hook is called outside a <Calendar> or <RangeCalendar> subtree), it throws immediately. The library throws because the year picker depends on the parent calendar's state (focused date, selection) to function.
Source
Thrown at packages/react/src/components/calendar-year-picker/use-calendar-state.ts:17
"use client";
import {use} from "react";
import {CalendarStateContext} from "react-aria-components/Calendar";
import {RangeCalendarStateContext} from "react-aria-components/RangeCalendar";
/**
* Returns the active Calendar or RangeCalendar state from RAC context.
* Must be used inside <Calendar> or <RangeCalendar>.
*/
function useCalendarOrRangeState() {
const calendarState = use(CalendarStateContext);
const rangeCalendarState = use(RangeCalendarStateContext);
const state = calendarState ?? rangeCalendarState;
if (!state) {
throw new Error(
"useCalendarOrRangeState must be used within a <Calendar> or <RangeCalendar> component.",
);
}
return state;
}
export {useCalendarOrRangeState};
View on GitHub (pinned to 7546fff813)
Solutions
- Move the component using this hook inside <Calendar>...</Calendar> or <RangeCalendar>...</RangeCalendar> so the context provider is an ancestor
- If you only need the year picker UI, compose it as <Calendar><CalendarYearPicker.Trigger/><CalendarYearPicker.Grid/></Calendar> instead of standalone parts
- If rendering in a portal or separate root, ensure the calendar context provider wraps that root, or pass state via props instead of context
- Check that you haven't destructured the compound component incorrectly (e.g., using internals like useCalendarOrRangeState directly)
Example fix
// before <CalendarYearPicker.Grid /> // rendered standalone // after <Calendar> <Calendar.YearPicker /> </Calendar>
Defensive patterns
Strategy: validation
Validate before calling
import {Calendar, RangeCalendar} from "@heroui/react";
// Ensure the consumer is a descendant:
// <Calendar> or <RangeCalendar> must wrap the component using calendar state. Type guard
// Not runtime-checkable generically; structurally, only use calendar internals
// inside components rendered as children of <Calendar>/<RangeCalendar>.
const isInsideCalendar = (el: HTMLElement | null) =>
!!el?.closest('[data-slot]'); // adjust to the calendar's data-slot value Prevention
- Only render calendar sub-parts as descendants of <Calendar>/<RangeCalendar>
- Wrap isolated sub-component tests/stories with the full calendar provider
- Avoid importing internal hooks like useCalendarOrRangeState in app code
When it happens
Trigger: Calling useCalendarOrRangeState() (or rendering a CalendarYearPicker part that uses it, e.g. CalendarYearPicker.Grid or Trigger) outside of a <Calendar> or <RangeCalendar> component tree; or rendering such parts in a portal/separate React root that is not a descendant of the calendar provider.
Common situations: Building a standalone year-picker, copying CalendarYearPicker internals into a custom component, extracting a sub-part into its own file and rendering it in isolation in a story/test, or accidental usage outside the compound component hierarchy.
Related errors
- useYearPicker must be used within a <Calendar> or <RangeCale
- CalendarYearPicker trigger components must be used within <C
- CalendarYearPicker components must be used within <CalendarY
- Ref was not connected to DOM element returned by custom `ren
AI-assisted analysis of heroui-inc/heroui@7546fff813 (2026-08-28).
Data as JSON: /api/errors/8ff3a62223ceee99.
Report an issue: GitHub.