Question

J'ai une telle méthode render() dans mon composant racine:

render: function() {
    return (
        <div className="question">
            <QuestionA question={this.props.question} author={this.props.author}/>
            <QuestionB yes={this.state.yes} no={this.state.no} />
            <div className="question-side-switcher" onClick={this.handleSideChanging}></div>
        </div>
    );
}

Là où je veux basculer le "actif" de la classe entre QuestionA et QuestionB composants lorsque l'utilisateur a cliqué sur le bouton.Comment puis-je faire cela?Gardez à l'esprit que QuestionA et QuestionB sont à définir leurs propres noms de classe dans leur render() méthodes.Par exemple QuestionB render():

render: function() {
    return (
        <section className="question-b-container">
            ...
        </section>
    );
}
Était-ce utile?

La solution

Il y a quelques façons de gérer cela.

Si vous souhaitez que le parent contrôle la classe supplémentaire, vous pouvez simplement le transmettre aux composants de l'enfant et les ajouter à son nom de classe existant ( Jsfiddle Demo ):

var QuestionA = React.createClass({
  render: function() {
    return <section className={this.props.className + " question-a-container"}>Section A</section>;
  }
});

var QuestionB = React.createClass({
  render: function() {
    return <section className={this.props.className + " question-b-container"}>Section B</section>;
  }
});

var Root = React.createClass({
  getInitialState: function() {
    return { question: 'a' };
  },

  render: function() {
    var qAclassName = this.state.question === 'a' ? 'active' : '';
    var qBclassName = this.state.question === 'b' ? 'active' : '';
    return (
      <div className="question">      
        <QuestionA className={qAclassName} />
        <QuestionB className={qBclassName} />
        <div className="question-side-switcher" onClick={this.handleSideChanging}>Change</div>
      </div>
    );
  },

  handleSideChanging: function() {
    this.setState({question: this.state.question === 'a' ? 'b' : 'a' });
  }
});

Cependant, il est probablement plus logique de laisser l'enfant à gérer le nom de la classe et d'envoyer simplement des données pour indiquer s'il doit définir sa classe active ( Jsfiddle Demo ):

// Using classSet to more easily create conditional class names;
// see http://facebook.github.io/react/docs/class-name-manipulation.html
var cx = React.addons.classSet;

var QuestionA = React.createClass({
  render: function() {
    // always set "question-a-container";
    // set "active" if we got a truthy prop named `active`
    var className = cx({
      "question-a-container": true,
      "active": this.props.active
    });
    return <section className={className}>Section A</section>;
  }
});

var QuestionB = React.createClass({
  render: function() {
    // always set "question-b-container";
    // set "active" if we got a truthy prop named `active`
    var className = cx({
      "question-b-container": true,
      "active": this.props.active
    });
    return <section className={className}>Section B</section>;
  }
});

var Root = React.createClass({
  getInitialState: function() {
    return { question: 'a' };
  },

  render: function() {
    return (
      <div className="question">
        {/* For each question, compare to state to see if it's active. */}
        <QuestionA active={this.state.question === 'a'} />
        <QuestionB active={this.state.question === 'b'} />
        <div className="question-side-switcher" onClick={this.handleSideChanging}>Change</div>
      </div>
    );
  },

  handleSideChanging: function() {
    this.setState({question: this.state.question === 'a' ? 'b' : 'a' });
  }
});

Autres conseils

Comme Brian Voelker mentionné dans le commentaires, la désormais officiel de la façon de manipuler les classes de Réagir est d'utiliser la les noms de classe utilitaire.

Vous pouvez définir deux composantes comme suit:

import React, { Component } from 'react'
import classNames from 'classnames'

class QuestionA extends Component {

  render () {

    const { active } = this.props
    const cx = classNames('question-a-container', { active })

    return (
      <section className={cx}></section>
    )
  }

}

Et tout simplement passer un active prop pour basculer l'homonyme de la classe.

J'ai eu un problème similaire à cela, j'ai créé un tiroir à onglets et je ne rangeais que le composant demandé avec le tabber, mais une telle solution n'était pas idéale car je perdais l'état de la composante enfant à chaque fois que je suis passé à une autre avecle tabber.

Pour éviter cela dans le rendu, j'appelle une fonction pour rendre tous mes enfants, dans cette fonction, j'allume chaque enfant dans un div et j'ignore le nom de classe nécessaire à la DIV, dans mon cas, je devais afficher un seul composant parTemps alors j'utilisais l'affichage: bloc ou aucun dépendant de la touche cliquée.

renderMyChilds() {
        var renderedComponents = this.props.children.map(function(child, _key) {
            if(this.state.drawerOpened == true) {
                var ElementToRender = child;
                var MyElement = (this.state.buttonSelected != _key) ? <div className="hiddenComponent"><ElementToRender /></div> : <div><ElementToRender /></div>;

            } else {
                var ElementToRender = child;
                var MyElement = <div><ElementToRender className="hiddenComponent" /></div>;
            }
            return (MyElement);
        }, this);
        return renderedComponents;
    }

.hiddencomomponent { Affichage: Aucun; }

.Visiblecomponent { bloc de visualisation; }

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top