[RFC] Add useDomTransition hook for better DX in DOM animations #33720
Moon-DaeSeung
started this conversation in
Ideas
Replies: 1 comment
-
Does the |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
[RFC] Add useDomTransition hook for better DX in DOM animations
Summary
Propose a built-in
useDomTransition
hook that leverages React 19's new useRef cleanup functionality to provide declarative DOM animations without requiring external libraries.Motivation
Current Pain Points in React DOM Animations
1. Library Dependency Hell
Currently, developers need heavy libraries for basic DOM transitions:
2. Complex State Management
Without libraries, developers resort to complex patterns:
3. Competitive Disadvantage
Svelte provides built-in animation directives (
in:
,out:
,transition:
), offering superior DX out of the box. React developers deserve the same level of built-in animation support.Detailed Design
Usage Example
const transition = useDomTransition();
return (
{show && (
<div ref={transition({
in: (element) => ({
duration: 300,
tick: (progress) => {
element.style.opacity = progress.toString();
}
}),
out: (element) => ({
duration: 300,
tick: (progress) => {
element.style.opacity = progress.toString();
}
})
})}>
Hello World! 👋
)} );
Implementation
"use client";
import { useRef, useCallback } from "react";
import { linear } from "../easing";
export interface TransitionConfig {
duration?: number;
easing?: (t: number) => number;
tick?: (t: number) => void;
}
export interface TransitionOptions {
in: (node: HTMLElement) => TransitionConfig | Promise;
out: (node: HTMLElement) => TransitionConfig | Promise;
}
// Enhanced useDomTransition - allows inline option specification
export const useDomTransition = () => {
const containerRef = useRef<HTMLElement | null>(null);
const optionsRef = useRef<TransitionOptions | null>(null);
const elementRef = useRef<HTMLElement | null>(null);
const originalNextSiblingRef = useRef<Element | null>(null);
const stableCallback = useCallback((element: HTMLElement | null) => {
if (!element || !optionsRef.current) return;
elementRef.current = element;
}, []);
// Function that receives options and returns ref callback
return (options: TransitionOptions) => {
optionsRef.current = options;
return stableCallback;
};
};
How it Works
The hook leverages React 19's new useRef cleanup capability:
in
transitionout
transitionThis approach eliminates the need for complex state management while providing smooth enter/exit animations.
Benefits
Developer Experience
Performance
Ecosystem Impact
Beta Was this translation helpful? Give feedback.
All reactions