web-dev-qa-db-ja.com

styled-componentでReactCSSTransitionGroupを使用する

私はCSSの伝統的な方法の代わりに styled-components を使用しています。しかし、それが ReactCSSTransitionGroup とどのように連携するかはわかりません。

基本的に、ReactCSSTransitionGroupはcssリソースで特定のクラス名を探し、そのライフサイクル全体でコンポーネントに適用します。ただし、styled-componentsでは、クラス名はなく、スタイルはコンポーネントに直接適用されます。

ReactCSSTransitionGroupを使用しないことを選択できることは知っています。2つの手法は互換性がないように見えるからです。しかし、styled-componentsのみを使用すると、コンポーネントがマウント解除されているとアニメーションをレンダリングできません。純粋なcssであり、コンポーネントのライフサイクルにアクセスできません。

任意のヘルプまたは推奨事項を歓迎します。

22
Stanley Luo

遷移をコンポーネントごとに異なるものにする必要があるため、別の回答で提案されている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を使用していることに注意してください。

30
Mike Goatly

Mike Goatlyのアプローチ は素晴らしいですが、動作させるために小さな変更を加える必要がありました。 <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>
    );
  }
}
6
Daniel Apt

スタイル付きコンポーネントで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>
)
2
Chiahao Lin

injectGlobal() styled-componentヘルパーメソッドを使用して、Reactアプリをブートストラップします。このメソッドを使用すると、CSSセレクターをあたかもスタイルすることができます。 d従来のCSSを使用している。

まず、CSSでテンプレートリテラルをエクスポートするJSファイルを作成します 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のクラスを記述するだけでも、うまく機能します。

2
AxeEffect