⚛️ React 19 lets you delete useEffect for DOM logic. 👇 👇 For years, integrating third-party DOM libraries (like GSAP, ResizeObserver, or vanilla JS animations) required a specific dance: 1. Create a useRef. 2. Create a useEffect. 3. Check if (ref.current). 4. Return a cleanup function. It separated the "Element" from the "Logic" that controlled it. React 19 introduces Ref Callback Cleanup. ❌ The Old Way: You had to synchronize a mutable ref with an effect. It was verbose and prone to "stale closure" bugs if you forgot dependencies. ✅ The Modern Way: Pass a function to the ref prop. React runs this function when the node mounts. If you return a function, React will automatically run it when the node unmounts. Why this is cleaner: 📉 Less Code: Logic is co-located with the element it affects. 🧠 No Hooks: You don't need useRef or useEffect for simple DOM integrations. ⚡ Safe: Handles node mounting/unmounting lifecycles perfectly. Note: This is perfect for things like ResizeObserver, IntersectionObserver, or auto-focus logic. #ReactJS #React19 #WebDevelopment #Frontend #JavaScript #CleanCode #SoftwareEngineering #TechTips #ReactHooks #Hooks #ReactTips #FrontrendDeveloper #DevloperTips
Sorry, this is a terrible idea. The last thing you want is huge piles of JavaScript in the JSX, especially for life cycle logic.
This is a great step forward — it fixes a long-standing friction point in React 👏 Ref Callback Cleanup finally aligns the DOM lifecycle with the logic that controls it, without using useEffect as generic glue. The biggest wins for me: 🔹 Less accidental complexity 🔹 No dependency arrays to forget (goodbye stale closures) 🔹 DOM integrations become declarative, not orchestrated For cases like ResizeObserver, IntersectionObserver, auto-focus, or animation libraries, this makes the code more predictable and localized — the side effect lives exactly where the element is created. React 19 isn’t just adding features, it’s removing unnecessary complexity. Really curious to see how this reshapes third-party DOM integrations going forward 🚀
Cleaner syntax, same fundamental issue: you still need to think about callback stability (useCallback), closure scope, and when React decides to re-run things. This doesn't remove complexity — it relocates it. The "dependency array problem" just moved from useEffect to useCallback wrapping your ref callback
I don’t think this is a good idea. In React, logic and markup are usually better kept separate.
As a frontend developer, this is a big win less boilerplate, fewer bugs, and much cleaner DOM integrations. React 19 is really pushing dev experience forward ⚛️🚀
It seams like everyone is surprised whereas we could do that before React 19
Callback refs themselves are old (from 2015), but the ability to return a cleanup function from callback refs is the new feature in React 19. This is the old way of doing it without a useEffect.
Not sure how i feel about moving that into the return 🫠
This is a really nice improvement in React 19 Ref callback cleanup makes DOM logic much simpler and cleaner. This will definitely reduce unnecessary useEffect usage. Great tip for modern React development!
Very cool I will try it in my next project. One thing that makes me worry is the missing dependency array tho. Can I use state in my resize observer and it will will properly update or will I have stale state in my listener?