Écriture d'une API pour les composants React, partie 1: ne créez pas d'accessoires conflictuels
Écriture d'une API pour les composants React, partie 2: donner des noms au comportement, pas à l'interaction
Écriture d'une API pour les composants React, partie 3: l'ordre des accessoires est important
Écriture d'une API pour React Components, Partie 4: Méfiez-vous de l'Apropacalypse!
Écriture d'une API pour les composants React, partie 5: il suffit d'utiliser la composition
Nous écrivons API pour les composants React, partie 6: nous créons la communication entre les composants
Nous avons un composant switch - Switch
, qui accepte prop, appelons-le something
instant.
Un développeur utilisant notre composant peut transmettre une fonction, et nous l'appellerons lorsque la valeur changera.

<Switch something={fn} />
React nous donne la possibilité d'appeler prop comme nous le voulons: handler
/ clickHandler
/ onClick
/ onToggle
, etc.
La convention selon laquelle le nom du gestionnaire d'événements doit commencer par on
, par exemple, onClick
, onClick
. En effet, la spécification HTML a de nombreux gestionnaires qui suivent déjà cette convention: onkeydown
, onchange
, onclick
, etc.
Réutiliser un accord existant est une excellente idée; les développeurs n'auront pas à se souvenir de quelque chose de nouveau.
OK, et onClick
?
<Switch onClick={fn} />
Ici, je ne suis pas partisan du nom onClick
, un tel nom suggère qu'un clic de souris est le seul moyen d'interagir avec ce composant.
Les utilisateurs d'un appareil mobile peuvent appuyer sur l'interrupteur avec un doigt ou le faire glisser vers la droite. Les utilisateurs malvoyants peuvent l'utiliser avec un logiciel de lecture d'écran et utiliser les touches du clavier.
En tant que développeur utilisant ce composant, je ne veux pas penser à la façon dont les utilisateurs finaux interagissent avec ce composant. Je veux juste attacher une fonction qui est appelée lorsque la valeur change.
Donnez des noms à votre API qui n'indiqueront pas un moyen d'interagir:
<Switch onToggle={fn} />
C'est logique, non? Basculez l' toggles
(bascule) entre deux valeurs.
Dans un composant, vous souhaiterez peut-être proxy toutes les interactions possibles dans la même fonction
function Switch(props) { return ( <div className="switch" /* */ onClick={props.onToggle} onKeyDown={function(event) { /* enter , event */ if (event.key === 'Enter') props.onToggle(event) }} onDrag={function(event) { /* */ if (event.toElement === rightSide) props.onToggle(event) }} /> ) }
Nous avons pris en compte toutes les options pour donner une API claire à nos utilisateurs (développeurs).
Parlons maintenant du composant de saisie de texte.

<TextInput />
HTML a un attribut onchange , la documentation React utilise onChange
dans ses exemples. Apparemment, il existe un consensus sur ce score.
<TextInput onChange={fn} />
Très simple.
Maintenant, mettons ces deux composants côte à côte.

<TextInput onChange={fn} /> <Switch onToggle={fn} />
Vous voyez quelque chose d'étrange?
Malgré le fait que les deux composants nécessitent le même comportement, prop est appelé différemment. Ces accessoires sont parfaits pour leurs composants respectifs, mais lorsque vous regardez vos composants ensemble, cela semble assez controversé.
Un développeur qui utilisera ces composants devra toujours vérifier le nom de l'accessoire avant de l'utiliser.
Voici donc l'astuce n ° 2: essayez d'obtenir des accessoires cohérents entre les composants . Le même comportement doit avoir le même accessoire pour tous les composants.
Ces conseils peuvent également être formulés comme suit: Efforcez - vous d'avoir une zone API minimale . Vous devez limiter le nombre d'API qu'un développeur doit maîtriser avant de pouvoir travailler de manière productive.
Je tiens à dire que tous les mérites à ce sujet reviennent à Sebastian Markbåge . (Sa présentation: Minimal API Surface Area )
La façon de mettre en œuvre ce conseil est de choisir un accessoire et de l'utiliser dans tous vos composants. Des deux accessoires que nous avons dans notre exemple, onChange
également dans la spécification HTML, donc certains développeurs peuvent le reconnaître.

<TextInput onChange={fn} /> <Switch onChange={fn} /> <Select onChange={fn} /> // etc.
La cohérence entre les composants et, par conséquent, la simplicité d'apprentissage de votre API l'emportent sur le choix de l'hélice «idéale» pour un seul composant.
Un petit bonus.
Parlons de la signature de cette fonction.
<TextInput onChange={fn} />
Le onChange
événements onChange
( fn
dans cet exemple) reçoit un argument - event
.
Cela fonctionne à chaque changement. Vous pouvez obtenir un tas d'informations utiles de cet événement.
function fn(event) { console.log(event.target)
Très probablement, la plupart des développeurs seront intéressés par event.target.value
afin de pouvoir l'utiliser pour d'autres tâches - utiliser dans l'état, soumettre le formulaire, etc.
Dans le cas de notre composant Switch
, chaque action représente un "événement" distinct - event
. Cet event
aura différentes propriétés pour cliquer et faire glisser. Comment pouvons-nous nous assurer que l'API est cohérente?
Nous pouvons définir manuellement event.target.value
pour chaque "événement":
function Switch(props) { const fireHandler = event => { const newValue = !oldValue event.target.value = newValue props.onChange(event) } return ( <div className="switch" /* */ onClick={fireHandler} onKeyDown={function(event) { if (event.key === 'Enter') fireHandler(event) }} onDrag={function(event) { if (event.toElement === rightSide) fireHandler(event) }} /> ) }