30

我正在使用样式组件而不是传统的 css 方式。但我不知道它如何与ReactCSSTransitionGroup一起工作。

基本上,ReactCSSTransitionGroup在 css 资源中查找某些类名,然后在其整个生命周期中应用于组件。但是,styled-components没有任何类名,样式直接应用于组件。

我知道我可以选择不使用ReactCSSTransitionGroup,因为这两种技术看起来不兼容。但是当我只使用时styled-components,似乎在卸载组件时我无法渲染任何动画 - 它是纯 css,无法访问组件的生命周期。

任何帮助或建议表示赞赏。

4

7 回答 7

47

我不想injectGlobal按照另一个答案中的建议使用,因为我需要使每个组件的转换不同。

事实证明这很简单 - 只需将转换类嵌套在组件的样式中即可:

import React from "react";
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
import styled from 'styled-components';

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;
        }`;

export default () => {

    return (
        <CSSTransitionGroup
            transitionName={transitionName}
            transitionAppear={true}
            transitionAppearTimeout={appearDuration}>
            <Container>
                This will have the appear transition applied!
            </Container>
        </CSSTransitionGroup>
    );
};

请注意,我使用的是较新的CSSTransitionGroup,而不是ReactCSSTransitionGroup,但它也应该适用。

于 2018-05-29T18:52:16.293 回答
14

Mike Goatly 的方法很棒,但我必须进行一些小改动才能使其发挥作用。我改变了<CSSTransition>'s 的道具,并使用了一个函数作为它的子函数。

请参阅下面的组件示例,该组件根据状态更改淡入/淡出:

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>
    );
  }
}
于 2018-08-18T13:26:56.703 回答
3

您可以在样式组件中使用 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>
)

于 2018-03-02T15:42:45.587 回答
2

在你的 React 应用程序被引导的地方使用injectGlobal()styled-component 辅助方法。使用这种方法,您可以设置任何 CSS 选择器的样式,就像使用传统 CSS 一样。

首先创建一个 JS 文件,使用您的 CSS 导出模板文字react-transition-group(请不要我使用 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即使您使用样式组件,它也可以很好地工作。

于 2017-07-21T05:19:08.290 回答
1

有一篇很棒的博客文章解释了如何做到这一点: https ://dev.to/terrierscript/styled-component--react-transition-group--very-simple-transition-jja

Transiton他们使用react-transition-group 提供 的低级组件: 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>
于 2020-10-14T15:34:31.083 回答
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']etc,因为 React 改变了这个组件中所有类的名称,因为我使用了withStyles. 也正因为如此,当我导出组件时,React 将我的类插入到该组件的 props 中,这就是为什么我还必须创建一个名为 classes 的变量来捕获这些类。

于 2020-03-03T20:17:26.923 回答
-7

在 CSS 中尝试 camelCase,如下所示。

.enter {

}
.enterActive { }
于 2017-05-01T03:25:54.083 回答