30% offEnding soon
ToggleRenderPropsLoading saved progress…

ToggleRenderProps

A render prop is a function prop that lets a component share behavior while its caller decides what to render. Implement ToggleRenderProps, a headless React component that owns one boolean and calls its child with the current value plus stable controls. The component must add no wrapper element.

Signature

function ToggleRenderProps(props: {
  initialOn?: unknown;
  children: (api: {
    on: boolean;
    toggle: () => void;
    setOn: React.Dispatch<React.SetStateAction<boolean>>;
    reset: () => void;
  }) => React.ReactNode;
}): React.ReactNode;

Examples

The child owns the button and its label:

React.createElement(
  ToggleRenderProps,
  { initialOn: true },
  ({ on, toggle }) =>
    React.createElement('button', { onClick: toggle }, on ? 'Mute' : 'Unmute'),
);
// first render: <button>Mute</button>
// after one click: <button>Unmute</button>

The same behavior can drive completely different markup:

React.createElement(ToggleRenderProps, null, ({ on, setOn, reset }) =>
  React.createElement('section', null,
    React.createElement('output', null, on ? 'open' : 'closed'),
    React.createElement('button', { onClick: () => setOn(true) }, 'Open'),
    React.createElement('button', { onClick: reset }, 'Reset'),
  ),
);

Notes

  • The first value is the baseline. Convert initialOn with Boolean once on mount. Later prop changes must neither overwrite live state nor change what reset restores.
  • Controls stay stable. toggle, setOn, and reset keep the same identities across renders. toggle must use a functional update so calls in one batch compose.
  • The child is current. Call the current child function on every render with exactly { on, toggle, setOn, reset }. Replacing that function must not reset state.
  • Validate the contract. Throw a clear TypeError if children is not a function.
  • Out of scope. Do not add a wrapper, controlled mode, context, element cloning, prop getters, persistence, or a separate hook export.