You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Transition组件内联过渡样式无法生效问题

问题根源

你的代码一共有5个直接导致效果异常的问题:

  • Transition组件属性名写错:你写的onMountEnter、onMountExit是不存在的无效属性,控制组件进入时挂载、退出后卸载的正确属性是mountOnEnter和unmountOnExit。属性失效直接导致模态框初始加载就被挂载渲染,不会等触发打开逻辑才出现。
  • 内联样式没有绑定到DOM:你给Modal组件传入了style属性,但Modal组件的根div元素只绑定了className,完全没有接收挂载传入的style属性,你写的opacity、transition规则根本没有应用到模态框元素上,自然不会有过渡效果。
  • 状态逻辑冲突:你给Modal传入的modalState是外层瞬时更新的布尔值,用这个值切换modal-open/modal-close类名,会和Transition的渐进式状态变化冲突,直接打断过渡流程。
  • 导入路径不规范:你从react-transition-group/cjs/Transition导入组件属于引用包内部构建产物,会绕过组件的属性校验逻辑,导致你写错属性名时没有控制台报错/警告,增加排查成本。
  • 体验逻辑问题:遮罩层Backdrop直接用{modalOpen && ...}做瞬时条件渲染,关闭模态框时遮罩会直接消失,无法和模态框的淡出动画同步。
修正步骤
  1. 修正Transition组件的属性,替换为正确的mountOnEnter、unmountOnExit,同时把导入路径改成标准导入:import { Transition } from "react-transition-group",timeout值和你写的过渡时长300ms保持一致即可。
  2. 修改Modal组件,把父组件传入的style属性绑定到组件根div元素上,让过渡样式能真正生效;删除依赖外层瞬时modalOpen状态切换类名的冲突逻辑,如果需要类名对应过渡状态,可以把Transition返回的state传给Modal,基于state值绑定对应类名。
  3. 把Backdrop的渲染逻辑移到Transition的渲染函数内部,和Modal同步接收过渡状态控制opacity,不要单独用modalOpen做条件渲染,保证遮罩和模态框的动画同步;同样给Backdrop组件加上style属性绑定逻辑。
修正后核心代码

App组件修正部分

import { Transition } from "react-transition-group";
// 其余导入保持不变

function App() {
  const [modalOpen, setModalOpen] = useState(false);

  const onOpenModalHandler = () => setModalOpen(true);
  const onCloseModalHandler = () => setModalOpen(false);

  return (
    <div className={classes["App"]}>
      <h1>React Animations</h1>
      <Transition 
        in={modalOpen} 
        timeout={300} 
        mountOnEnter 
        unmountOnExit
      >
        {(state) => {
          const transitionStyle = {
            transition: `opacity 300ms ease-out`,
            opacity: state === "exiting" || state === "exited" ? 0 : 1,
          }
          return (
            <>
              {ReactDOM.createPortal(
                <Modal
                  closeModal={onCloseModalHandler}
                  style={transitionStyle}
                />,
                document.getElementById("modal")
              )}
              {ReactDOM.createPortal(
                <Backdrop style={transitionStyle}/>,
                document.getElementById("backdrop")
              )}
            </>
          )
        }}
      </Transition>
      <button className={"Button"} onClick={onOpenModalHandler}>
        Open Modal
      </button>
      <h3>Animating Lists</h3>
      <List />
    </div>
  );
}

export default App;

Modal组件修正部分

import classes from "./Modal.module.css";

const Modal = (props) => {
  const onCloseModalHandler = () => {
    props.closeModal();
  };

  return (
    // 绑定传入的内联样式到根元素
    <div className={classes.Modal} style={props.style}>
      <h1>A Modal</h1>
      <button className="Button" onClick={onCloseModalHandler}>
        Dismiss
      </button>
    </div>
  );
};

export default Modal;

注意:Backdrop组件需要做和Modal相同的修改,在根div上绑定style={props.style},否则遮罩层的过渡效果不会生效。

内容的提问来源于stack exchange,提问作者Nijaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:09:15