web-dev-qa-db-fra.com

Comment aller de jQuery à React.js?

Je lisais sur React depuis quelques jours maintenant. Je peux comprendre la plupart de ce que je regarde, mais je ne suis pas tout à fait sûr de ma capacité à l'écrire. travaille sur une petite application Web qui exécute toute sa génération html avec jQuery et en ajoutant des éléments les uns aux autres. J'aimerais essayer de reconstruire le tout avec React Ceci JSFiddle est un petit exemple du genre de chose sur laquelle je travaille. Comment l'écririez-vous avec React?

JS:

function remove() {
    this.remove();
}

function timed_append_new_element() {
    setTimeout(function () {
        var added_content = $("<span />", {
            class: "added_content",
            text: "Click to close",
            click: remove
        });
        container.append(added_content);
    }, 3000);
}

function append_new_element() {
    var added_content = $("<span />", {
        class: "timed_added_content",
        text: "Click to close",
        click: remove
    });
    container.append(added_content);
}


var container = $("<div />", {
    class: "container"
});
var header = $("<span />", {
    class: "header",
    text: "jQuery to React.js Header"
});
var add_button = $("<button />", {
    class: "add_button",
    text: "Add Element",
    click: append_new_element
});
var timed_add_button = $("<button />", {
    class: "add_button",
    text: "Add Element in 3 seconds",
    click: timed_append_new_element
});
container.append(header);
container.append(add_button);
container.append(timed_add_button);
$("body").append(container);
71
EasilyBaffled

Il faut garder à l’esprit quelques principes de base qui peuvent vous aider à créer une bonne React:

Votre interface utilisateur doit être fonction des données

Dans de nombreuses applications de style "jQuery soup", la logique commerciale de l'application, les données de l'application et le code d'interaction de l'interface utilisateur sont tous entremêlés. Cela rend ce type d’application difficile à déboguer et, surtout, à développer. React, à l'instar de nombreux frameworks d'application côté client modernes, renforce l'idée que l'interface utilisateur n'est qu'une représentation de vos données. Si vous souhaitez que votre interface utilisateur change, vous devez modifier une partie des données et autoriser le système de liaison utilisé par la structure pour mettre à jour l'interface utilisateur pour vous.

Dans React, chaque composant est (idéalement) une fonction de deux données: les propriétés transmises à l'instance du composant, et le état géré par le composant. intérieurement. Étant donné les mêmes propriétés (ou "accessoires") et le même état, le composant doit être rendu de la même manière.

Cela peut être un peu une idée abstraite sans exemples concrets, alors gardez-le à l'esprit lorsque nous allons de l'avant.

Ne touchez pas le DOM

Dans React, encore plus que d’autres frameworks liés aux données, vous devriez essayer de ne pas manipuler directement le DOM, si possible. La plupart des caractéristiques de performance et de complexité de React ne sont possibles que parce que React utilise un DOM virtuel avec des algorithmes de diffing en interne pour fonctionner sur le DOM réel. Chaque fois que vous construisez un composant Manipulation DOM, vous devriez vous demander si vous pouvez créer la même fonctionnalité de manière plus idiomatique avec les fonctionnalités DOM virtuelles de React.

Bien sûr, vous devrez parfois accéder au DOM ou incorporer un plugin jQuery sans le reconstruire dans React. Pour de tels moments, React vous donne de bons crochets du cycle de vie des composants que vous pouvez utiliser pour vous assurer que les performances de React ne souffrent pas trop (ou, dans certains cas, pour éviter que votre composant ne soit brisé).

Ne pas manipuler le DOM va de pair avec "l'interface utilisateur en fonction des données" ci-dessus.

Inverser le flux de données

Dans une grande application React, il peut être difficile de savoir quel sous-composant gère une donnée d'application donnée. Pour cette raison, le React = L’équipe recommande de conserver la logique de manipulation des données dans un emplacement central.La manière la plus simple de procéder consiste à transférer les rappels en composants enfants; il existe également une architecture développée sur Facebook, appelée Flux, qui possède son propre site Web .

Créer des composants composables

Souvent, il peut être tentant d'écrire un gros composant qui gère plusieurs états ou plusieurs éléments de logique d'interface utilisateur. Lorsque cela est possible (et dans des limites raisonnables), vous devez envisager de diviser des composants plus volumineux en composants plus petits qui fonctionnent sur une seule donnée ou logique d’interface utilisateur. Cela facilite grandement l’extension et le déplacement des éléments de votre application.

Méfiez-vous des données mutables

Étant donné que l'état des composants ne doit être mis à jour que via des appels à this.setState depuis le composant, il est utile de se méfier des données mutables. Ceci est d'autant plus vrai lorsque plusieurs fonctions (ou composants!) Peuvent mettre à jour l'objet mutable dans le même tick; React peut essayer de traiter les modifications d'état par lot et vous pouvez perdre les mises à jour! Comme mentionné dans les commentaires de Eliseu Monar, envisagez de cloner des objets mutables avant de les muter. React a aides à l'immuabilité qui peut aider.

Une autre option consiste à ne pas conserver du tout l'état des structures de données mutables; le modèle de flux, mentionné ci-dessus, est une interprétation intéressante de cette idée.


Il y a un excellent article sur le React site appelé Thinking in React qui explique comment vous pouvez transformer une idée ou une maquette en un React et encouragez vivement à la parcourir. À titre d'exemple concret, examinons le code que vous avez fourni. Vous avez essentiellement un élément de données à gérer: une liste de contenu existant dans le container. Toutes les modifications apportées à votre interface utilisateur peuvent être représentées par des ajouts, des suppressions et des modifications de ces données.

En appliquant les principes ci-dessus, votre application finale pourrait ressembler à ceci:

/** @jsx React.DOM */

var Application = React.createClass({
  getInitialState: function() {
    return {
      content: []
    };
  },

  render: function() {
    return (
      <div className="container">
        <span className="header">jQuery to React.js Header</span>
        <button className="add_button"
                onClick={this.addContent}>Add Element</button>
        <button className="add_button"
                onClick={this.timedAddContent}>Add Element in 3 Seconds</button>
        {this.state.content.map(function(content) {
          return <ContentItem content={content} removeItem={this.removeItem} />;
        }.bind(this))}
      </div>
    );
  },

  addContent: function() {
    var newItem = {className: "added_content", text: "Click to close"},
        content = this.state.content,
        newContent = React.addons.update(content, {$Push: [newItem]});
    this.setState({content: newContent});
  },

  timedAddContent: function() {
    setTimeout(function() {
      var newItem = {className: "timed_added_content", text: "Click to close"},
          content = this.state.content,
          newContent = React.addons.update(content, {$Push: [newItem]});
      this.setState({content: newContent});
    }.bind(this), 3000);
  },

  removeItem: function(item) {
    var content = this.state.content,
        index = content.indexOf(item);
    if (index > -1) {
      var newContent = React.addons.update(content, {$splice: [[index, 1]]});
      this.setState({content: newContent});
    }
  }
});

var ContentItem = React.createClass({
  propTypes: {
    content: React.PropTypes.object.isRequired,
    removeItem: React.PropTypes.func.isRequired
  },

  render: function() {
    return <span className={this.props.content.className}
                 onClick={this.onRemove}>{this.props.content.text}</span>;
  },

  onRemove: function() {
    this.props.removeItem(this.props.content);
  }
});

React.renderComponent(<Application />, document.body);

Vous pouvez voir le code en action dans ce JSFiddle : http://jsfiddle.net/BinaryMuse/D59yP/

L’application est composée de deux composants: un composant de niveau supérieur appelé Application, qui gère (dans son état) un tableau appelé content et un composant appelé ContentItem, qui représente l'interface utilisateur et le comportement d'un seul élément de ce tableau. La méthode Application de render renvoie un élément ContentItem pour chaque élément du tableau de contenu.

Une chose à noter est que toute la logique de gestion des valeurs dans le tableau content est gérée dans le composant Application; les composants ContentItem sont passés à la méthode Application de référence à removeItem, à laquelle le ContentItem délègue lorsque l'utilisateur clique dessus . Cela conserve toute la logique de manipulation de l'état dans le composant de niveau supérieur.

169
Michelle Tilley