J'utilise styled-components au lieu de la manière traditionnelle de css. Mais je ne sais pas comment cela peut fonctionner avec ReactCSSTransitionGroup .
En règle générale, ReactCSSTransitionGroup
recherche certains noms de classe dans la ressource css, puis les applique à un composant tout au long de son cycle de vie. Cependant, avec styled-components
, il n'y a pas de nom de classe, les styles sont appliqués directement aux composants.
Je sais que je peux choisir de ne pas utiliser ReactCSSTransitionGroup
car les deux techniques ne semblent pas compatibles. Mais lorsque je n'utilise que styled-components
, il semble que je ne puisse pas restituer d'animation lorsqu'un composant est démonté - c'est du css pur, il est impossible d'accéder au cycle de vie du composant.
Toute aide ou recommandation est appréciée.
Je ne voulais pas utiliser injectGlobal
comme suggéré dans une autre réponse car je devais rendre les transitions différentes par composant.
Cela se révèle être assez facile - imbriquer les classes de transition dans le style du composant:
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>
);
};
Notez que j'utilise la plus récente CSSTransitionGroup
, plutôt que ReactCSSTransitionGroup
, mais cela devrait également fonctionner pour cela.
L'approche de Mike Goatly est géniale, mais j'ai dû faire de petits changements pour que cela fonctionne. J'ai changé les accessoires du <CSSTransition>
et utilisé une fonction comme son enfant.
Voir ci-dessous pour un exemple de composant dont l'entrée et la sortie sont fondues en fonction d'un changement d'état:
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>
);
}
}
Utilisez la méthode d'assistance injectGlobal()
styled-Component où votre application React est démarrée. Avec cette méthode, vous pouvez appeler n'importe quel sélecteur CSS comme si vous utilisiez du CSS conventionnel.
Commencez par créer un fichier JS exportant un littéral de modèle avec votre CSS pour la syntaxe react-transition-group
(veuillez ne pas utiliser la nouvelle version 2.1 des noms de classe):
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;
Puis sur votre fichier de point d’entrée:
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]
);
Toutefois, si vous utilisez uniquement CSS/SASS/Less pour écrire les classes pour le react-trasition-group
même lorsque vous utilisez des composants stylés, cela fonctionne également bien.
Vous pouvez utiliser le sélecteur de variable css dans styled-components. Comme ça:
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>
)