我使用styled-components而不是传统的css方式。但我不知道它如何与ReactCSSTransitionGroup一起工作。
基本上,ReactCSSTransitionGroup
在css资源中查找某些类名,然后在整个生命周期中应用于组件。但是,对于styled-components
,没有任何类名,样式直接应用于组件。
我知道我可以选择不使用ReactCSSTransitionGroup
,因为这两种技术看起来并不兼容。但是当我只使用styled-components
时,似乎我无法在卸载组件时渲染任何动画 - 它是纯粹的CSS,无法访问组件的生命周期。
感谢任何帮助或建议。
答案 0 :(得分:26)
我不想按照另一个答案的建议使用injectGlobal
因为我需要为每个组件制作不同的转换。
事实证明这很简单 - 只需将过渡类嵌套在组件的样式中:
import React from "react";
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
import styled from 'styled-components';
export default () => {
const appearDuration = 500;
const transitionName = `example`;
const Container = styled.section`
font-size: 1.5em;
padding: 0;
margin: 0;
&.${transitionName}-appear {
opacity: 0.01;
}
&.${transitionName}-appear-active {
opacity: 1;
transition: opacity ${appearDuration}ms ease-out;
}`;
return (
<CSSTransitionGroup
transitionName={transitionName}
transitionAppear={true}
transitionAppearTimeout={appearDuration}>
<Container>
This will have the appear transition applied!
</Container>
</CSSTransitionGroup>
);
};
请注意,我使用的是较新的CSSTransitionGroup
,而不是ReactCSSTransitionGroup
,但它也适用于此。
答案 1 :(得分:3)
Mike Goatly's approach很棒,但是我必须进行一些小的更改才能使其正常工作。我更改了<CSSTransition>
的道具,并使用了一个函数作为其子项。
有关组件的示例,请参见下文,该组件会根据状态变化淡入/淡出:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { CSSTransition } from "react-transition-group";
import styled from "styled-components";
const Box = styled.div`
width: 300px;
height: 300px;
background: red;
transition: opacity 0.3s;
// enter from
&.fade-enter {
opacity: 0;
}
// enter to
&.fade-enter-active {
opacity: 1;
}
// exit from
&.fade-exit {
opacity: 1;
}
// exit to
&.fade-exit-active {
opacity: 0;
}
}`;
export default class App extends Component {
constructor() {
super();
this.state = {
active: true
};
setInterval(() => this.setState({ active: !this.state.active }), 1000);
}
render() {
return (
<CSSTransition
in={this.state.active}
classNames="fade"
timeout={300}
unmountOnExit
>
{() => <Box />}
</CSSTransition>
);
}
}
答案 2 :(得分:2)
使用启动了React应用程序的injectGlobal()
样式组件帮助程序方法。使用此方法,您可以设置任何CSS选择器的样式,就像您使用传统的CSS一样。
首先创建一个JS文件,用react-transition-group
的CSS导出模板文字(请不要使用v2.1新的类名语法):
globalCss.js
const globalCss = `
.transition-classes {
/* The double class name is to add more specifity */
/* so that this CSS has preference over the component one. */
/* Try removing it, you may not need it if properties don't collide */
/* https://www.styled-components.com/docs/advanced#issues-with-specificity */
&-enter&-enter {
}
&-enter&-enter-active {
}
&-exit&-exit {
}
&-exit&-exit-active {
}
}
`;
export default globalCss;
然后在您的入口点文件:
index.jsx
import { injectGlobal } from "styled-components";
import globalCss from "./globalCss.js";
injectGlobal`${ globalCss }`; // <-- This will do the trick
ReactDOM.render(
<Provider store={ Store } >
<HashRouter >
<Route path="/" component={ Component1 } />
<Route path="/" component={ Component2 } />
</HashRouter>
</Provider>,
document.getElementsByClassName("react-app")[0]
);
但是,如果您只使用CSS / SASS / Less来编写react-trasition-group
的类,即使您使用样式化组件,它也可以正常运行。
答案 3 :(得分:2)
您可以在样式组件中使用css变量选择器。像这样:
const Animation = styled(ReactCSSTransitionGroup)`
${({ transitionName }) => `.${transitionName}-enter`} {
opacity: 0;
}
${({transitionName}) => `.${transitionName}-leave`} {
opacity: 1;
}
`
const animationID = 'some-hashed-text'
const AnimationComponent = props => (
<Animation
transitionName={animationID}
transitionEnterTimeout={0.1}
transitionLeaveTimeout={2000}
>
<div>some content</div>
</Animation>
)
答案 4 :(得分:0)
import React from "react";
import { CSSTransition } from 'react-transition-group';
const styles = theme => ({
'fade-enter':{
opacity: 0,
},
'fade-enter-active':{
opacity: 1,
transition: "opacity 300ms"
},
'fade-exit':{
opacity: 1,
},
'fade-exit-active':{
opacity: 0,
transition: "opacity 300ms"
},
})
class myAnimatedComponent extends React.Component {
constructor(props){
super(props);
}
render(){
let {classes} = this.props;
return (
<CSSTransition
in={this.props.conditionVariable}
classNames={{
enter: classes['fade-enter'],
enterActive: classes['fade-enter-active'],
exit: classes['fade-exit'],
exitActive: classes['fade-exit-active'],
}}
timeout={300}
unmountOnExit>
<span>This will have the transition applied to it!</span>
</CSSTransition>
);
}
};
export default (styles)(myAnimatedComponent);
我必须使用classes['fade-enter']
等,因为由于我使用了withStyles
,因此React更改了此组件中所有类的名称。也正因为如此,当我导出组件时,React将我的类插入到该组件的props中,这就是为什么我还必须创建一个名为classes的变量来捕获这些类的原因。
答案 5 :(得分:0)
有一篇很棒的博客文章,解释了如何做到这一点: https://dev.to/terrierscript/styled-component--react-transition-group--very-simple-transition-jja
他们使用了来自react-transition-group的低级Transiton
组件:
http://reactcommunity.org/react-transition-group/transition
// This is overly simplified, but styles change depend on state from Transition
const MyStyledComponent = styled.div`
transform: translateY(${({ state }) => (state === 'exited' ? "0" : "-100%")});
transition: transform 2s;
`
const App = () =>
<Transition in={animate} timeout={500}>
{(state) => (
// state change: exited -> entering -> entered -> exiting -> exited
<MyStyledComponent state={state}>Hello</MyStyledComponent>
)}
</Transition>
答案 6 :(得分:-5)
尝试使用CSS中的camelCase,如下所示。
.enter {
}
.enterActive { }