React 19 ready, emotionally questionable

gReact
Hooks

Hooks for problems nobody should have.

Technically functional React 19 hooks with reasons to exist ranging from “barely defensible” to “please just write the value directly.”

useStateWithoutSetter inaction
const status = useStateWithoutSetter("initial");

// There is no setter.
// status remains "initial".
// React has been involved for no reason.

Bad ideas, accurate naming

Small abstractions with enormous audacity.

Every public hook works. Whether any of them should be called is a separate and much shorter discussion.

💗

React involved

Even values that need no hook can now require one.

Types included

TypeScript can describe every questionable decision precisely.

🦄

No coherent strategy

Constants, browser melodrama, and intervals coexist without explanation.

Tree-shakeable

Your bundler can remove the hooks you were sensible enough not to import.

More indirection, no benefit

React abstractions with an obvious better alternative.

Write 0. Use the value directly. Keep the setter. These are all excellent ways to avoid this package.

Why nobody should switch

  • Several APIs replace one line with one hook call.
  • The jokes are more stable than the product strategy.
  • React was already difficult enough without this.

Read the fine print

Hook documentation

Every public export, including the alternatives you should use instead.

Utility

useInterval(callback, delay)

Runs a callback repeatedly. This one is suspiciously defensible.

Signature

useInterval(callback: () => void, delay: number | null);

Example

const [tick, setTick] = useState(0);
useInterval(() => setTick((n) => n + 1), 1000);
Drama

useDramaticPause(delay?)

Calls pointer inactivity a dramatic pause because “idle” lacked theatre.

Signature

useDramaticPause(delay?: number): boolean;

Example

const dramatic = useDramaticPause(1000);
Drama

useTabJealousy(options?)

Makes a browser tab resent visitors who briefly leave it.

Signature

useTabJealousy(options?: UseTabJealousyOptions): string | null;

Example

const complaint = useTabJealousy();
Excuse

useKeyMashExcuse(options?)

Writes an alibi for a burst of keyboard nonsense.

Signature

useKeyMashExcuse(options?: UseKeyMashExcuseOptions): string | null;

Example

const excuse = useKeyMashExcuse({ threshold: 4 });
Prophecy

useDoomScrollOracle(options?)

Predicts absolutely nothing from how far someone scrolls.

Signature

useDoomScrollOracle(options?: UseDoomScrollOracleOptions): string | null;

Example

const prophecy = useDoomScrollOracle({ distance: 800 });
Applause

useFocusFanfare(options?)

Gives every focus change an entirely silent fanfare.

Signature

useFocusFanfare(options?: UseFocusFanfareOptions): string | null;

Example

const fanfare = useFocusFanfare();
Evidence

useClipboardSuspicion(options?)

Treats every copy event as evidence of an unspecified crime.

Signature

useClipboardSuspicion(options?: UseClipboardSuspicionOptions): string | null;

Example

const suspicion = useClipboardSuspicion();
Regret

useBackButtonRegret(options?)

Judges history traversal without knowing whether it was Back or Forward.

Signature

useBackButtonRegret(options?: UseBackButtonRegretOptions): string | null;

Example

const regret = useBackButtonRegret();
Constant

useZeroZero()

Returns 0 through React. A reasonable person would write 0.

Signature

useZeroZero(): number;

Example

const zero = useZeroZero();
Identity

useSameSame<T>(value)

Returns the value supplied. Using the value directly remains available.

Signature

useSameSame<T>(value: T): T;

Example

const same = useSameSame(value);
New

useStateWithoutSetter<T>(initialValue)

Creates state, discards its setter, and leaves the initial value trapped forever.

Signature

useStateWithoutSetter<T>(initialValue: T): T;

Example

const permanentlyInitial = useStateWithoutSetter("initial");

A reasonable person would use the value directly, or keep the setter. This hook should not exist.

New

useRefRef<T>(initialValue)

Stores a stable ref inside another stable ref, doubling the indirection without improving the value.

Signature

useRefRef<T>(initialValue: T): RefObject<RefObject<T>>;

Example

const refRef = useRefRef("unnecessarily deep");
const value = refRef.current.current;

A reasonable person would use useRef(initialValue). This hook should not exist.

New

useEffectWithoutEffect()

Schedules a React effect whose entire effect is having no effect.

Signature

useEffectWithoutEffect(): void;

Example

useEffectWithoutEffect();

A reasonable person would do nothing at all. This hook should not exist.