2016-07-15 13 views
1

ReactCSSTransitionGroup verwendet eine CSS-Datei zum Definieren und Speichern von Übergängen. Das ist schön und funktioniert gut. Was aber, wenn eine Komponente eine variable Übergangskonfiguration benötigt, z. B. eine Variable transition-duration, die einen Wert von 0ms bis 10000ms annehmen kann? Wie würde ich den Wert transition-duration innerhalb der JavaScript-Klasse der Komponente ändern, wenn sie in einer CSS-Datei gespeichert ist?Variable Übergänge in React mit ReactCSSTransitionGroup

Beispiel:

Angenommen, Sie eine Diashow-Komponente machen wollen, und Sie wollen eine Option implementieren, um die Fading-Dauer (die Zeit, die Animation von einer Folie zur anderen verblassen nimmt) zu ändern . Sie rufen die Komponente wie folgt aus:

<Slideshow fadeDuration={1000}> 

Dies ist, wie die Komponente, die Übergänge zu dem Schiebeelement hinzufügt, die gerendert wird werden:

render: function() { 
    return (
    <div> 
     <ReactCSSTransitionGroup 
     transitionName="example" 
     transitionEnterTimeout={500} 
     transitionLeaveTimeout={300}> 
     {this.slide} 
     </ReactCSSTransitionGroup> 
    </div> 
); 
} 

Dies ist die CSS-Datei von ReactCSSTransitionGroup benötigt definieren die Übergänge:

.example-enter { 
    opacity: 0.01; 
} 

.example-enter.example-enter-active { 
    opacity: 1; 
    transition: opacity 500ms ease-in; 
} 

.example-leave { 
    opacity: 1; 
} 

.example-leave.example-leave-active { 
    opacity: 0.01; 
    transition: opacity 300ms ease-in; 
} 

Nun, wie verwende ich props.fadeDuration innerhalb der Komponente den Wert von transition-duration, die innerhalb t legt sich ändern er css datei?

Bisher ist die einzige Sache, die mir in den Sinn kam, war, dass ich die ReactCSSTransitionGroup entfernen müssen und die Übergänge manuell mit refs und die 'Style Object' 'transition' property erstellen. Ist das der Weg zu gehen? Oder wie würde ich es tun?

Antwort

2

Sie können jss Bibliothek verwenden, um CSS von Javascript zu manipulieren. Es ist eine sehr gute Bibliothek und löst viele Fälle. Schau mal.

AKTUALISIERT Ich werde Ihnen zeigen, wie es zu benutzen. In wichtigen Fällen Komponenten jss-react wie folgt aussehen:

import React, { Component } from 'react' 
import useSheet from 'react-jss' 

// You can use jss directly too! 
import jss from 'jss' 
import vendorPrefixer from 'jss-vendor-prefixer' 
jss.use(vendorPrefixer()) 

const styles = { 
    button: { 
    'background-color': 'yellow' 
    }, 
    label: { 
    'font-weight': 'bold' 
    } 
} 

class Button extends Component { 
    render() { 
    const { classes } = this.props.sheet 

    return (
     <div className={classes.button}> 
     <span className={classes.label}> 
      {this.props.children} 
     </span> 
     </div> 
    ) 
    } 
} 

export default useSheet(Button, styles) 

Styles sind außerhalb der Komponente definiert, und dann wird ein higher-order component verwendet, es zu wickeln und die Stile zu injizieren. In großen Fällen ist es in Ordnung, aber da wir CSS-Regeln von innerhalb der Komponente hinzufügen müssen, müssen wir einen anderen Ansatz verwenden. Wir müssen JSS als child element instead of higher order component verwenden. Das erlaubt uns, Regeln aus den Komponenten mit Hilfe der Methode addRules() hinzuzufügen.

import React, { Component } from 'react'; 
import ReactCSSTransitionGroup from 'react-addons-css-transition-group' 
import useSheet from 'react-jss' 
import jss from 'jss' 

let styles = {}; 
const sheet = jss.createStyleSheet(styles, {named: false}) 
class Foo extends Component { 
    constructor(props) { 
    super(props); 
    this.state ={ 
     isVisible: false 
    } 
    } 
    toggle() { 
    this.setState({ 
     isVisible: !this.state.isVisible 
    }) 
    } 

    render() { 
    const duration = 500 
    const { classes } = sheet 
    sheet.addRules(
     {    
     '.example-enter': { 
      opacity: 0.01 
     }, 
     '.example-enter-active': { 
      color: 'red', 
      opacity: 1, 
      transition: 'opacity ' + duration + 'ms ease-in' 
     }, 
     '.example-leave': { 
      opacity: 1 
     }, 
     '.example-leave-active': { 
      opacity: 0.01, 
      transition: 'opacity '+ duration +'ms ease-in' 
     } 
     } 
    ); 
    return (
     <div className={classes.red}> 
     <Jss sheet={sheet} /> 
     <a onClick={this.toggle.bind(this)}>Click</a> 
      <ReactCSSTransitionGroup 
      transitionName="example" 
      transitionEnterTimeout={10} 
      transitionLeaveTimeout={600}> 
      { this.state.isVisible ? <div>Visible</div> : null} 
     </ReactCSSTransitionGroup> 
     </div> 
); 
    } 
} 


const map = new WeakMap() 

class Jss extends Component { 
    componentWillMount() { 
    const {sheet} = this.props 
    const counter = map.get(sheet) || 0 
    if (!counter) sheet.attach() 
    map.set(sheet, counter + 1) 
    } 

    componentWillUnmount() { 
    const {sheet} = this.props 
    const counter = map.get(sheet) - 1 
    if (counter) { 
     map.set(sheet, counter) 
    } else { 
     sheet.detach() 
     map.delete(sheet) 
    } 
    } 

    render() { 
    return null 
    } 
} 

export default Foo 

Eine Sache zu beachten. Standardmäßig fügt jss den Klassen einige Suffixe hinzu, um globale Selektoren zu entfernen und sie zu isolieren. Eine Klasse sieht folgendermaßen aus: .example-enter-441163035. Es ist sehr angenehm, diesen Ansatz zu verwenden, wenn wir className Attribute manuell setzen, wie zum Beispiel: <div className={classes.button}>.So, oder müssen Sie Übergang Klassen manuell einstellen, wie folgt aus:

<ReactCSSTransitionGroup 
    transitionName={{ 
    enter: classes.example-enter, 
    enterActive: classes.example-enter-active, 
    leave: classes.example-leave, 
    leaveActive: classes.example-leave-active. 
    }} 
    transitionEnterTimeout={10} 
    transitionLeaveTimeout={600}> 

Oder Sie haben globale Selektoren zu verwenden, indem named Option als false eingestellt wird, wenn Blatt Einleitung (wie ich in meinem Beispiel):

const sheet = jss.createStyleSheet(styles, {named: false}) 

Hoffe es hilft! Werfen Sie trotzdem einen Blick auf diese Bibliothek. Es ist wirklich cool und fördert einen sehr interessanten Ansatz für CSS.

+0

Könnten Sie mir bitte ein kurzes Beispiel geben, wie man das mit jss macht? – Rotareti

+0

Sicher, nur einen Moment. –

+1

Sorry, ich musste gehen, konnte das Problem nicht posten. Ich werde morgen mit einem Beispiel zurück sein. –