使用材质 UI 时动画未触发

The*_*ted 2 css reactjs material-ui

我在向现有应用程序添加材质 UI 时遇到了问题。基本上发生的情况是,当我向模态中添加材质 UI 组件时,模态的输入动画不会触发。将 Material UI 降级到 1.0.0 或删除所有 MUI 组件可以解决该问题。此外,使用任何其他 UI 库都不会导致此问题。

https://codesandbox.io/s/mui-animation-issue-mgph3

import React, { useState, useEffect } from "react";
import styled from "styled-components";
import Test from "./Test";

const Overlay = styled.div`
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 10000;
`;

const Modal = styled.div`
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100px;
  height: 100px;
  align-items: center;
  background: white;
`;

const modalsComponentLookupTable = {
  Test
};

const ModalContainer = ({ setModals, children }) => {
  const [modalStyle, setModalStyle] = useState({
    opacity: 0,
    transition: "opacity 2000ms",
    willChange: "opacity",
    transitionTimingFunction: "cubic-bezier(0.165, 0.840, 0.440, 1.000)"
  });
  const [bgStyle, setBgStyle] = useState({
    background: "rgba(0, 0, 0, 1)",
    willChange: "opacity",
    transition: "opacity 2000ms cubic-bezier(0.165, 0.840, 0.440, 1.000)",
    opacity: 0
  });
  const unMountStyle = () => {
    // css for unmount animation
    setModalStyle({
      opacity: 0,
      transition: "opacity 2200ms",
      willChange: "opacity",
      transitionTimingFunction: "cubic-bezier(0.165, 0.840, 0.440, 1.000)"
    });
    setBgStyle({
      background: "rgba(0, 0, 0, 1)",
      willChange: "opacity",
      transition: "opacity 2200ms cubic-bezier(0.165, 0.840, 0.440, 1.000)",
      opacity: 0
    });
  };

  const mountStyle = () => {
    // css for mount animation
    setModalStyle({
      opacity: 1,
      transition: "opacity: 2000ms",
      willChange: "opacity",
      transitionTimingFunction: "cubic-bezier(0.165, 0.840, 0.440, 1.000)"
    });

    setBgStyle({
      willChange: "opacity",
      opacity: 1,
      background: "rgba(0, 0, 0, 1)",
      transition: "opacity 2000ms cubic-bezier(0.165, 0.840, 0.440, 1.000)"
    });
  };

  useEffect(() => {
    mountStyle();
  }, []);

  const back = e => {
    e.stopPropagation();
    unMountStyle();
    setTimeout(() => setModals([]), 2200);
  };

  return (
    <Overlay onClick={back} style={bgStyle}>
      <Modal style={modalStyle}>{children}</Modal>
    </Overlay>
  );
};

const ModalsManager = ({ modals, setModals }) => {
  const renderedModals = modals.map(modalDescription => {
    const ModalComponent = modalsComponentLookupTable[modalDescription];

    return (
      <ModalContainer setModals={setModals}>
        <ModalComponent />
      </ModalContainer>
    );
  });

  return <span>{renderedModals}</span>;
};

export default ModalsManager;
Run Code Online (Sandbox Code Playgroud)

Test组件包含任何类型的MUI组件时,不会触发进入动画。控制台中没有错误。显然,我的代码中的某些内容确实触发了这个问题,因为我已经在他们的 github 上打开了一个问题,他们说这不是他们的库的问题:https ://github.com/mui-org/material-ui/issues/17888

Rya*_*ell 5

我已经充分隔离了这一点,确信这不是Material -UI 的问题,而是用于过渡动画的方法的脆弱性。

要打破它,我所要做的就是包含一个在安装上立即重新渲染的组件(在 或 中componentDidMountuseLayoutEffect这是TransitionGroup 所做的事情,并由TouchRipple 使用TransitionGroup,而TouchRipple 又被多个 Material-UI 组件(例如按钮)使用。ButtonBase

将组件更改Test为以下内容足以导致不良行为:

import React from "react";

const RerenderOnMount = () => {
  const [, setMyState] = React.useState(false);
  React.useLayoutEffect(() => {
    setMyState(true);
  }, []);
  return null;
};
const Test = () => {
  return (
    <div
      css={`
        height: 100px;
        width: 100px;
        z-index: 5;
      `}
      onClick={e => e.stopPropagation()}
    >
      <div>
        Test
        <RerenderOnMount />
      </div>
    </div>
  );
};

export default Test;
Run Code Online (Sandbox Code Playgroud)

编辑MUI动画问题

在上面的示例中,仍然重现了您的问题,没有使用 Material-UI 组件。

我相信子元素的重新渲染会影响(延迟)浏览器第一次尝试绘制模式的时间,并导致浏览器无法识别您调用时发生的转换mountStyle(即行为与如果您最初使用了“安装”样式,而不是识别从默认样式到安装样式的过渡)。在 React 中获得正确的计时以确保浏览器进行转换的技巧是人们通常使用React-transition-group来帮助解决此问题的原因(就像 Material-UI 所做的那样)。

我能够通过在 中调用mountStylevia来使您的代码正常工作,但我不能保证此黑客在其他情况下(取决于模式中的内容)或不同的浏览器中不会出现问题,我建议使用重新设计转换以管理进入/退出状态。这是我的黑客的工作版本:https://codesandbox.io/s/mui-animation-issue-505rjsetTimeoutuseEffectreact-transition-groupsetTimeout