Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
FREEDOM251

Freedom251 › Blog › accessibility

React Dialog Exit Animation FAQ: Unmounting, Portals, and Transition Events

By Freedom251 Team · · 8 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A dialog cannot animate after React has removed it. Keep the dialog and backdrop mounted, switch them to a closing state, and unmount only when the exit transition has completed. A portal changes where those nodes are placed in the DOM; it does not change their React lifecycle or provide an exit callback.

The reliable implementation is therefore a presence state plus a completion signal: a guarded onTransitionEnd, a transition-library callback, or a supported React <ViewTransition> boundary. During the closing phase, preserve focus and dismissal behavior until the UI is actually gone.

As an Amazon Associate I earn from qualifying purchases.

Why conditional unmounting stops an exit animation

This pattern removes the element immediately:

{open && <Dialog />}

When open becomes false, React stops rendering Dialog in that commit. The browser no longer has a dialog element on which to apply a CSS transition, so there is nothing left to animate. A closing class added in the same render cannot help if the element is removed in that render.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Separate the state that describes the requested interaction from the state that describes whether the DOM should exist:

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.
  • open records the caller’s intent.
  • phase (for example, closed, open, or closing) controls presence and CSS.

Opening changes the phase to open. Closing changes it to closing while the dialog remains rendered. Only the transition-completion handler changes the phase to closed.

A presence-state implementation that works with a portal

The following example uses a panel opacity transition. The same lifecycle can drive a transform, a backdrop, or both. The timeout is a safety net, not the primary signal.

import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';

const EXIT_MS = 180;

export function Dialog({ open, onClose }) {
  const [phase, setPhase] = useState('closed');
  const fallback = useRef(null);

  useEffect(() => {
    if (open) {
      setPhase('open');
      return;
    }
    setPhase(current => current === 'open' ? 'closing' : current);
  }, [open]);

  useEffect(() => {
    window.clearTimeout(fallback.current);
    if (phase === 'closing') {
      fallback.current = window.setTimeout(() => {
        setPhase('closed');
      }, EXIT_MS + 50);
    }
    return () => window.clearTimeout(fallback.current);
  }, [phase]);

  function handleTransitionEnd(event) {
    if (event.target !== event.currentTarget) return;
    if (event.propertyName !== 'opacity') return;
    if (phase === 'closing') setPhase('closed');
  }

  if (phase === 'closed') return null;

  return createPortal(
    <div
      className="dialog-layer"
      data-phase={phase}
      onTransitionEnd={handleTransitionEnd}
      role="presentation"
    >
      <div
        className="dialog-backdrop"
        onClick={onClose}
        aria-hidden="true"
      />
      <section
        className="dialog-panel"
        role="dialog"
        aria-modal="true"
        aria-labelledby="dialog-title"
      >
        <h2 id="dialog-title">Confirm action</h2>
        <button type="button" onClick={onClose}>Close</button>
      </section>
    </div>,
    document.body
  );
}

A matching stylesheet might be:

.dialog-layer {
  opacity: 0;
  transition: opacity 180ms ease;
}
.dialog-layer[data-phase="open"] {
  opacity: 1;
}
.dialog-layer[data-phase="closing"] {
  opacity: 0;
}

Because the transition is on the layer that owns onTransitionEnd, the handler can use event.target === event.currentTarget. If the panel or backdrop owns the transition instead, attach the handler there or use a deliberately chosen completion element.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Opening and closing races

If the user reopens the dialog before the fade-out finishes, the open effect returns the phase to open. The cleanup in the timeout effect cancels the old fallback, so a stale close cannot unmount the newly reopened dialog. If you animate panel and backdrop with different durations, decide which one controls removal; usually that is the longest or the element whose disappearance defines the interaction.

Using React’s transition events safely

React exposes the CSS transition event through onTransitionEnd. The event includes propertyName, elapsedTime, and pseudoElement; see the React common DOM components reference. A dialog often produces several events: opacity and transform may finish separately, and nested controls can emit their own events.

Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.

For that reason, do not treat the first bubbled event as proof that the dialog has finished:

  • Check event.target === event.currentTarget so a child transition cannot close the parent.
  • Check the expected propertyName, such as opacity.
  • Check that the component is still in the closing phase.
  • Use a fallback for disabled transitions, reduced-motion rules, interrupted transitions, or a browser situation in which no completion event is delivered.

A zero-duration transition may complete without the signal your logic expects. A timeout should match the CSS duration and include only a small safety margin. If the duration is configurable, derive both the CSS custom property and the JavaScript fallback from one value rather than maintaining unrelated numbers.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What a portal changes—and what it does not

React’s createPortal reference states that “A portal only changes the physical placement of the DOM node.” The JSX remains a child of the component that renders it, context is preserved, and events bubble according to the React tree rather than the DOM tree.

Consequently, a portal neither blocks nor prolongs an exit animation. The same presence state and completion callback work whether the dialog is rendered beside its trigger or under document.body. A click inside a portaled dialog can reach a React ancestor that is not a DOM ancestor; call stopPropagation() where that would otherwise trigger an unrelated page handler, or move the portal’s owner in the React tree.

Focus and dismissal during the closing phase

Keep modal behavior coherent while the closing pixels are still visible:

Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by
  • Return focus to the element that opened the dialog after unmount, not when the close request is first received.
  • Keep Escape handling and an explicit close button available until the closing phase is complete, unless your product deliberately disables repeated dismissal.
  • Keep role="dialog", aria-modal="true", and the accessible name on the dialog element while it is present.
  • Prevent background interaction according to your modal strategy; a fading overlay that no longer blocks clicks can let users activate the page behind it.
  • Test keyboard focus with the dialog portaled, because React-tree event bubbling does not replace focus management.

Transition managers: let a library retain the DOM

A transition component can own the presence state and expose a completion callback. This avoids duplicating event filtering, but its API and timing rules are library-specific.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

MUI Modal transitions

The MUI Modal documentation describes placing a transition component as the modal’s direct child and passing an in prop. The transition can call onEnter and onExited; “Call the onExited callback prop when the exit transition is completed.” Unmount the content from that completion callback, not when the close request is made. MUI’s modal content is unmounted when closed by default, while keepMounted preserves it when that behavior is needed.

React Modal timeout transitions

React Modal’s transition documentation uses closeTimeoutMS. The value must match the CSS or style duration, and the modal should not be conditionally rendered away during the close transition. This is a duration-based contract, so changing CSS without changing the configured timeout can cut off the animation or leave an invisible element mounted.

Do not mix callback names or props between libraries. Verify the installed version’s documentation, and determine whether the library expects the transition wrapper, the modal, or its child to remain mounted.

React <ViewTransition> for tree removal

React’s <ViewTransition> reference documents enter and exit animations for trees added or removed during a Transition. It also documents an onExit callback that can return a cleanup function. This approach lets React coordinate the visual transition around a component that is being removed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.

Support depends on the React release and rendering setup used by the application. Confirm that the installed version exposes the API and that the removal occurs inside the Transition pattern required by the documentation. If you assign explicit transition names, keep them globally unique; the reference notes that a shared transition with the same name takes precedence over enter and exit transitions.

ViewTransition is not a drop-in replacement for focus or modal semantics. Continue to manage focus, Escape, backdrop clicks, and background inertness independently.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Native <dialog> and CSS-driven closing

When the interaction fits native dialog behavior, the platform can manage much of the modal semantics. MDN’s HTML dialog element reference shows a CSS approach using @starting-style and transitions on opacity, transform, overlay, and display. The example uses allow-discrete for the discrete overlay and display properties.

These CSS features do not have identical support in every browser version. Check support for the browsers your audience actually uses, and provide a non-animated fallback. Native dialog methods such as showModal() and close() also impose a lifecycle different from a purely conditional React element; coordinate React state with the element’s open state rather than allowing the two to drift.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choosing an exit-animation strategy

Approach Lifecycle control Timing source Compatibility and complexity
Local presence state Your component keeps the DOM through closing, then unmounts. Actual transition event plus a fallback timeout. Works with portals and ordinary CSS; you must handle races, multiple properties, and accessibility.
Transition manager Library retains children and invokes an exit callback. Library callback or configured duration. Less lifecycle code, but props and unmount rules vary by library and version.
React <ViewTransition> React coordinates a removed tree inside a Transition. View Transition lifecycle and callbacks. Requires a React release and renderer that support the API; verify naming and setup.
Native <dialog> CSS Browser dialog element plus CSS open/close states. CSS transitions, including discrete properties where supported. Strong native semantics when suitable; browser support for newer CSS features varies.

Choose based on the interaction, not on whether the dialog is portaled. The important decisions are who retains the DOM, what event or callback proves completion, how interrupted closes are handled, and how focus is restored.

Troubleshooting common failures

The dialog disappears instantly

Look for a parent expression such as {open && <Dialog />} or a modal component that unmounts by default. Move conditional removal behind a presence phase, enable the library’s keep-mounted option where appropriate, or use its documented transition wrapper.

The close callback never fires

Confirm that the transition is nonzero, the expected property actually changes, and the handler is attached to the element that owns the transition. Filtered events can also be filtered too aggressively: inspect propertyName and whether the event target is a child. Retain the timeout fallback.

The event fires too early

A nested button, icon, or backdrop may be bubbling its own transition event. Require target === currentTarget and the specific property. If panel and backdrop durations differ, make the intended controlling element explicit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reopening leaves the dialog unmounted or stuck transparent

Cancel the pending fallback when the phase returns to open, and ensure the opening state is rendered before relying on a transition. Do not leave a stale timer that can set the phase to closed after a reopen.

Reduced motion breaks the lifecycle

A reduced-motion stylesheet may set the duration to zero. Treat that as a valid path: either call the completion logic when the computed duration is zero or let the fallback close immediately. The dialog must remain usable without animation.

Implementation checklist

  • Keep the dialog mounted while its visual state is closing.
  • Use one authoritative completion path and a bounded fallback.
  • Filter transition events by target, current target, property, and phase.
  • Cancel timers when the dialog reopens or unmounts.
  • Align JavaScript timeouts with the actual CSS duration.
  • Decide whether the panel or the backdrop controls removal when durations differ.
  • Keep focus, Escape, labeling, and background blocking correct until removal.
  • Test portal bubbling separately from DOM ancestry.
  • Verify the installed React or transition-library version before using its API.
  • Provide a no-animation path for reduced motion and unsupported CSS features.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

accessibilityCSS Transitionsdialogexit animationportalsReact

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.