API de composants React élégantes avec des fonctions en tant qu'enfants

Modèle de blog 35

réagir
Nous pouvons développer des API de composants React assez élégantes en utilisant des fonctions en tant qu'enfants dans les composants React. Prenons par exemple un composant Dropdown. Si nous voulons qu'il soit flexible en laissant la structure DOM à l'utilisateur, nous aurions besoin d'un moyen de désigner les éléments à bascule du menu déroulant. Une façon est avec le data-toggle attribut:

Ouvrez
Cependant, cela nécessitera la configuration manuelle d'écouteurs d'événements sur de vrais nœuds DOM, par exemple le componentDidMount La méthode sur ce composant pourrait ressembler à ceci :
composantDidMount() { const togglers = ReactDOM .findDOMNode(this) .querySelectorAll('[data-toggle]'); Array.prototype.forEach.call(togglers, toggler => { toggler.addEventListener('click', this.toggle); }); },

Une solution plus élégante consiste à exposer le composant toggle méthode à ses enfants en utilisant une fonction en tant qu'enfant :

  {basculer =>

}

 

De cette façon, nous utilisons le système d'événements de React au lieu des événements DOM bruts, et nous n'aurions pas besoin d'implémenter componentDidMount du tout.
Lorsque vous toggle s'appelle, le opened La classe CSS sera activée sur le div élément. En d’autres termes, le composant générerait un DOM qui ressemble à ceci :

 
et quand le toggle la fonction est appelée, le opened la classe est ajoutée à l'élément :

 
L'implémentation de ce composant Dropdown ressemble à ceci :

const cx = require('noms de classe'); const EnhancedWithClickOutside = require('react-click-outside'); const React = require('réagir'); const Dropdown = React.createClass({ getInitialState() { return {open: false, }; }, handleClick(e) { // Ferme la liste déroulante lorsque vous cliquez sur un élément de menu if (this.state.opened && e.target.tagName === 'A') { this.setState({ ouvert : false }); } }, handleClickOutside(e) { if (!this.state.opened) return; this.setState({ ouvert : false } ); , toggle() { this.setState({ open: !this.state.opened }); }, render() { const child = this.props.children(this.toggle); return React.cloneElement(child, { className); : cx( child.props.className, 'dropdown', this.state.opened && 'opened' ), onClick : this.handleClick, } }, }); module.exports = améliorerAvecClickOutside(Dropdown);

this.props.children est la fonction enfant du composant Dropdown, et elle est appelée avec le toggle méthode. Cela renvoie un élément React, le div, que nous clonons pour ajouter le dropdown et opened cours de CSS.
Une discussion de ce modèle et d'autres cas d'utilisation réels peut être trouvée ici.