Prop Collections and Prop Getters help reusable hooks expose interaction logic through flexible, accessible APIs.
A reusable hook may require consumers to manually connect state, event handlers, and accessibility attributes.
<buttonaria-pressed={on}onClick={toggle}>Toggle</button>
As the component grows, consumers must remember to wire every required prop correctly.
A prop collection is a ready-made props object returned by a hook.
function useCounter() {const [count, setCount] = useState(0);return {count,counterProps: {children: count,onClick: () => setCount(c => c + 1),},};}
Usage:
const { counterProps } = useCounter();<button {...counterProps} />;
Advantages: Simple and convenient for common use cases.
Limitation: Customizing individual props or event handlers can be awkward.
A prop getter is a function that generates props while allowing consumers to supply custom values and handlers.
function useToggle() {const [on, setOn] = useState(false);const toggle = () => setOn(value => !value);function getTogglerProps({onClick,...props}: React.ComponentPropsWithoutRef<"button"> = {}) {return {...props,"aria-pressed": on,onClick: (event: React.MouseEvent<HTMLButtonElement>) => {onClick?.(event);if (!event.defaultPrevented) {toggle();}},};}return { on, getTogglerProps };}
Usage:
const { getTogglerProps } = useToggle();<button{...getTogglerProps({onClick: () => console.log("Custom logic"),className: "toggle-button",})}>Toggle</button>;
The getter combines the consumer’s custom props with the hook’s internal behavior.
event.preventDefault() prevents the toggle.aria-pressed value.The order of prop spreading is intentional: internal aria-pressed and onClick behavior take precedence over conflicting consumer props.