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
我已经充分隔离了这一点,确信这不是Material -UI 的问题,而是用于过渡动画的方法的脆弱性。
要打破它,我所要做的就是包含一个在安装上立即重新渲染的组件(在 或 中componentDidMount)useLayoutEffect。这是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)
在上面的示例中,仍然重现了您的问题,没有使用 Material-UI 组件。
我相信子元素的重新渲染会影响(延迟)浏览器第一次尝试绘制模式的时间,并导致浏览器无法识别您调用时发生的转换mountStyle(即行为与如果您最初使用了“安装”样式,而不是识别从默认样式到安装样式的过渡)。在 React 中获得正确的计时以确保浏览器进行转换的技巧是人们通常使用React-transition-group来帮助解决此问题的原因(就像 Material-UI 所做的那样)。
我能够通过在 中调用mountStylevia来使您的代码正常工作,但我不能保证此黑客在其他情况下(取决于模式中的内容)或不同的浏览器中不会出现问题,我建议使用重新设计转换以管理进入/退出状态。这是我的黑客的工作版本:https://codesandbox.io/s/mui-animation-issue-505rj。setTimeoutuseEffectreact-transition-groupsetTimeout
| 归档时间: |
|
| 查看次数: |
7263 次 |
| 最近记录: |