web-dev-qa-db-fra.com

Extension des composants React.js

L'une des choses que j'apprécie le plus chez Backbone.js est la simplicité et l'élégance de l'héritage. Je commence à me familiariser avec React et je ne trouve rien dans Rea qui ressemble à ce code Backbone.

var Vehicle = Backbone.View.extend({
    methodA: function() { // ... }
    methodB: function() { // ... }
    methodC: function() { // ... }
});

var Airplane = Vehicle.extend({
    methodC: function() {
        // Overwrite methodC from super
    }
});

En réagit nous avons des mixins , et en utilisant ceux-ci, nous pourrions nous approcher un peu de l'exemple ci-dessus si nous procédions ainsi

var vehicleMethods = {
    methodA: function() { // ... }
    methodB: function() { // ... }
}

var Vehicle = React.createClass({
    mixins: [vehicleMethods]
    methodC: function() { 
        // Define method C for vehicle
    }
});

var Airplane = React.createClass({
    mixins: [vehicleMethods]
    methodC: function() {
        // Define method C again for airplane
    }
});

C’est moins répétitif que de définir encore et encore le même contenu, mais cela ne semble pas être aussi flexible que la méthode Backbone. Par exemple, j'obtiens une erreur si j'essaie de redéfinir/écraser une méthode qui existe dans l'un de mes mixins. En plus de cela, la manière React.js est plus de code pour moi d'écrire.

Rea possède des fonctions incroyablement intelligentes, et il me semble que c’est davantage le cas de moi qui n’arrive pas à savoir comment le faire correctement que c’est comme si une fonction manquait dans React.

Tous les indicateurs sont grandement appréciés.

67
Ahrengot

Pour obtenir quelque chose qui ressemble à l'héritage (en fait une composition comme indiqué dans les commentaires), vous pouvez créer un Airplane dans votre exemple un Vehicle. Si vous souhaitez exposer des méthodes sur Vehicle dans le composant Airplane, vous pouvez utiliser un ref et les connecter un par un. Ce n’est pas exactement un héritage (c’est en fait une composition ), en particulier parce que le this.refs.vehicle ne sera accessible qu'après le montage du composant.

var Vehicle = React.createClass({
    ...
});

var Airplane = React.createClass({
    methodA: function() {
      if (this.refs != null) return this.refs.vehicle.methodA();
    },
    ...
    render: function() {
        return (
            <Vehicle ref="vehicle">
                <h1>J/K I'm an airplane</h1>
            </Vehicle>
        );
    }
});

Il convient également de mentionner que, dans le documentation officielle de React , ils préfèrent la composition à l'héritage:

Alors, qu'en est-il de l'héritage? Sur Facebook, nous utilisons React dans des milliers de composants, et nous n’avons trouvé aucun cas d’utilisation où nous vous recommandons de créer des hiérarchies d’héritage.

Les accessoires et la composition vous offrent toute la flexibilité dont vous avez besoin pour personnaliser l'apparence et le comportement d'un composant de manière explicite et sûre. N'oubliez pas que les composants peuvent accepter des accessoires arbitraires, y compris des valeurs primitives, des éléments React, ou des fonctions.

Si vous souhaitez réutiliser des fonctionnalités non graphiques entre composants, nous vous suggérons de les extraire dans un module JavaScript séparé. Les composants peuvent l'importer et utiliser cette fonction, cet objet ou cette classe sans l'étendre.

Il est également intéressant de noter qu’en utilisant ES2015/ES6 +, vous pouvez également écarter les accessoires d’objet du composant Airplane au composant Vehicle.

render: function() {
    return (
        <Vehicle {...this.props}>
            <h1>J/K I'm an airplane</h1>
        </Vehicle>
    );
}
59
Ross Allen

Si vous utilisez le package NPM webpack + babel + rea mis en place dans votre projet, dans la mise en œuvre de ES6 OOP), cela devrait être aussi simple que cela:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class BaseComponentClass extends Component {
  componentDidMount() {} 
  render() { return (<div>Base Component</div>) }
}
class InheritedComponentClass extends BaseComponentClass {
  // componentDidMount is inherited
  render() { return (<div>Inherited Component</div>) } // render is overridden 
}
ReactDOM.render(<InheritedComponentClass></InheritedComponentClass>, 
     document.getElementById('InheritedComponentClassHolder'));

Remarque: Voici un kit de démarrage simple avec une telle configuration: https://github.com/alicoding/react-webpack-babel

4
Ashot