Fermer

octobre 12, 2021

API React utiles pour créer des composants flexibles avec TypeScript —


Résumé rapide ↬

React with JSX est un outil fantastique pour créer des composants faciles à utiliser. Les composants dactylographiés font du plaisir absolu pour les développeurs d'intégrer vos composants dans leurs applications et d'explorer vos API. Découvrez trois API React moins connues qui peuvent faire passer vos composants au niveau supérieur et vous aider à créer des composants React encore meilleurs dans cet article.

Avez-vous déjà utilisé React.createElement directement ? Qu'en est-il de React.cloneElement ? React, c'est plus que simplement transformer votre JSX en HTML. Bien plus, et pour vous aider à améliorer vos connaissances sur les API moins connues (mais très utiles) avec lesquelles la bibliothèque React est livrée. Nous allons passer en revue quelques-uns d'entre eux et certains de leurs cas d'utilisation qui peuvent considérablement améliorer l'intégration et l'utilité de vos composants.

Dans cet article, nous passerons en revue quelques API React utiles qui ne sont pas aussi courantes. connu mais extrêmement utile pour les développeurs Web. Les lecteurs doivent être expérimentés avec la syntaxe React et JSX, la connaissance de Typescript est utile mais pas nécessaire. Les lecteurs repartiront avec tout ce qu'ils doivent savoir afin d'améliorer considérablement les composants React lors de leur utilisation dans les applications React.

React.cloneElement

La plupart des développeurs n'ont peut-être jamais entendu parler de cloneElement ou jamais utilisé ce. Il a été introduit relativement récemment pour remplacer la fonction désormais obsolète cloneWithProps. cloneElement clone un élément, il vous permet également de fusionner de nouveaux accessoires avec l'élément existant, de les modifier ou de les remplacer comme bon vous semble. Cela ouvre des options extrêmement puissantes pour créer des API de classe mondiale pour les composants fonctionnels. Jetez un œil à la signature.

function cloneElement( element, props?, ...children)

Voici la version condensée de Typescript :

function cloneElement(
   élément : ReactElement,
   props ? : Attributs HTML,
   ...children: ReactNode[]): ReactElement

Vous pouvez prendre un élément, le modifier, voire remplacer ses enfants, puis le renvoyer en tant que nouvel élément. Jetez un œil à l'exemple suivant. Disons que nous voulons créer un composant TabBar de liens. Cela pourrait ressembler à ceci.

export interface ITabbarProps {
  liens : {titre : chaîne, URL : chaîne}[]
}
 
Exporter la fonction par défaut Tabbar (accessoires : ITabbarProps) {
 revenir (
   <>
     {props.links.map((e, i) =>
       {e.title}
     )}
   >
 )
}

Le TabBar est une liste de liens, mais nous avons besoin d'un moyen de définir deux éléments de données, le titre du lien et l'URL. Nous voudrons donc une structure de données transmise avec ces informations. Ainsi, notre développeur ferait en sorte que notre composant soit ainsi.

function App() {
 revenir (
   
 )
}

C'est très bien, mais que se passe-t-il si l'utilisateur souhaite afficher les éléments button au lieu des éléments a ? Eh bien, nous pourrions ajouter une autre propriété qui indique au composant quel type d'élément rendre.

Mais vous pouvez voir à quel point cela deviendra rapidement lourd, nous aurions besoin de prendre en charge de plus en plus de propriétés pour gérer divers cas d'utilisation et cas limites pour flexibilité maximale.

Voici une meilleure façon, en utilisant React.cloneElement.

Nous commencerons par changer notre interface pour référencer le type ReactNode. Il s'agit d'un type générique qui englobe tout ce que React peut rendre, généralement des éléments JSX, mais peut également être des chaînes et même null. Ceci est utile pour indiquer que vous souhaitez accepter les composants React ou JSX comme arguments en ligne.

export interface ITabbarProps {
 liens : ReactNode[]
}

Maintenant, nous demandons à l'utilisateur de nous donner des éléments React, et nous les rendrons comme nous le souhaitons.

function Tabbar(props: ITabbarProps) {
 revenir (
   <>
     {props.links.map((e, i) =>
       e // renvoie simplement l'élément lui-même
     )}
   >
 )
}

Ceci est parfaitement valide et rendrait nos éléments. Mais nous oublions deux ou trois choses. D'une part, clé ! Nous voulons ajouter des clés pour que React puisse rendre nos listes efficacement. Nous voulons également modifier nos éléments pour effectuer les transformations nécessaires afin qu'ils s'intègrent dans notre style, comme classNameet ainsi de suite.

Nous pouvons le faire avec React.cloneElementet une autre fonction React.isValidElement pour vérifier que l'argument est conforme à ce que nous attendons !

Plus après le saut ! Continuez à lire ci-dessous ↓

React.isValidElement

Cette fonction renvoie true si un élément est un élément React valide et que React peut le restituer. Voici un exemple de modification des éléments de l'exemple précédent.

function Tabbar(props: ITabbarProps) {
 revenir (
   <>
     {props.links.map((e, i) =>
       isValidElement(e) && cloneElement(e, {clé : `${i}`, className : 'bold'})
     )}
   >
 )
}

Ici, nous ajoutons un accessoire clé à chaque élément que nous transmettons et mettons chaque lien en gras en même temps ! Nous pouvons maintenant accepter des éléments React arbitraires comme accessoires comme ceci :

function App() {
 revenir (
   <Tabbar links={[
     Premier,
     
   ]} />
 )
}

Nous pouvons remplacer n'importe quel accessoire défini sur un élément et accepter facilement différents types d'éléments, ce qui rend notre composant beaucoup plus flexible et facile à utiliser.

L'avantage ici est que si nous voulions définir un gestionnaire personnalisé onClick pour notre bouton, nous pourrions le faire. Accepter les éléments React eux-mêmes en tant qu'arguments est un moyen puissant de donner de la flexibilité à la conception de vos composants.

useState Setter Function

Utilisez des crochets ! Le hook useState est extrêmement utile et constitue une API fantastique pour créer rapidement un état dans vos composants, comme suit :

const [myValue, setMyValue] = useState()

En raison de l'exécution de JavaScript, il peut avoir des hoquet. Vous vous souvenez des fermetures ?

Dans certaines situations, une variable peut ne pas être la valeur correcte en raison du contexte dans lequel elle se trouve, comme dans les boucles for généralement ou les événements asynchrones. Cela est dû à la portée lexicale. Lorsqu'une nouvelle fonction est créée, la portée lexicale est préservée. Comme il n'y a pas de nouvelle fonction, la portée lexicale de newVal n'est pas conservée, et donc la valeur est en fait déréférencée au moment où elle est utilisée.

setTimeout(() => {
 setMyValue(newVal) // cela ne fonctionnera pas
}, 1000)

Ce que vous devez faire, c'est utiliser le setter en tant que fonction. En créant une nouvelle fonction, la référence des variables est préservée dans la portée lexicale et le currentVal est transmis par le crochet React useState lui-même.

setTimeout(() => {
 setMyValue((currentVal) => {
   retourner newVal
 })
}, 1000)

Cela garantira que votre valeur est correctement mise à jour car la fonction setter est appelée dans le bon contexte. Ce que React fait ici, c'est appeler votre fonction dans le bon contexte pour qu'une mise à jour de l'état de React se produise. Cela peut également être utilisé dans d'autres situations où il est utile d'agir sur la valeur actuelle, React appelle votre fonction avec le premier argument comme valeur actuelle.

Remarque : Pour une lecture supplémentaire sur le sujet de l'async et des fermetures, je recommande de lire " useState Lazy Initialization And Function Updates" par Kent C. Dodds.

JSX Inline Functions

Voici une démo Codepen d'une fonction JSX en ligne :

Voir le stylo [Hello World in React](https://codepen.io/smashingmag/pen/QWgQQKR) par Gaurav Khanna.

Voir le stylo Hello World in React par Gaurav Khanna.

Pas exactement une API React par exemple.

JSX prend en charge les fonctions en ligne et il peut être très utile pour déclarer une logique simple avec des variables en ligne, tant qu'il renvoie un élément JSX.

Voici un exemple :

function App() {
  revenir (
    <>
     {(() => {
       const darkMode = isDarkMode()
       if (mode sombre) {
         revenir (
           
) } autre { revenir (
) // on peut déclarer JSX n'importe où ! } })()} // n'oubliez pas d'appeler la fonction ! > ) }

Ici, nous déclarons du code à l'intérieur de JSX, nous pouvons exécuter du code arbitraire et tout ce que nous avons à faire est de renvoyer une fonction JSX à rendre.

Nous pouvons le rendre conditionnel ou simplement exécuter une logique. Prenez note des parenthèses entourant la fonction en ligne. De plus, en particulier ici où nous appelons cette fonction, nous pourrions même passer un argument dans cette fonction à partir du contexte environnant si nous le voulions !

})()}

Cela peut être utile dans les situations où vous souhaitez agir sur une structure de données de collection d'une manière plus complexe qu'un .map standard permet à l'intérieur d'un élément JSX.

function App() {
  revenir (
    <>
      {(() => {
        laissez str = ''
        pour (let i = 0; i < 10; i++) {
          str += je
        }
        retour (

{str}

) })()} > ) }

Ici, nous pouvons exécuter du code pour parcourir un ensemble de nombres, puis les afficher en ligne. Si vous utilisez un générateur de site statique tel que Gatsby, cette étape sera également pré-calculée. HTMLElements ou d'autres composants. Principalement utile pour saisir correctement une interface d'éléments dans Typescript, mais l'application réelle est la même pour JavaScript.

Voici un exemple simple, disons que nous voulons remplacer une ou deux propriétés d'un élément buttonmais donnent toujours aux développeurs la possibilité d'ajouter d'autres propriétés au bouton. Tels que le réglage type='button' ou type='submit'. Nous ne voulons évidemment pas recréer l'intégralité de l'élément de bouton, nous voulons simplement étendre ses propriétés existantes et peut-être ajouter une autre prop.

import React, { ButtonHTMLAttributes } de 'react'

Nous importons d'abord React et la classe ButtonHTMLAttributes un type qui englobe les accessoires d'un HTMLButtonElement. Vous pouvez lire le code source de ce type d'interface ici :

Et vous pouvez voir que l'équipe React a réimplémenté toutes les API du Web dans TypeScript afin qu'elles puissent être vérifiées.

Ensuite, nous déclarons notre interface comme suit , en ajoutant notre propriété status.

interface ButtonProps étend ButtonHTMLAttributes {
 statut ? : 'primaire' | 'info' | 'danger'
}

Et enfin, nous faisons deux ou trois choses. Nous utilisons la déstructuration ES6 pour extraire les accessoires qui nous intéressent (status et children), et déclarons toutes les autres propriétés comme rest. Et dans notre sortie JSX, nous renvoyons un élément de bouton, avec une structuration ES6 pour ajouter des propriétés supplémentaires à cet élément.

function Button(props: ButtonProps) {
 const { status, children, ...rest } = props // reste a d'autres props
 revenir (
   
 )
}

Alors maintenant, un développeur peut ajouter un accessoire type ou tout autre accessoire qu'un bouton aurait généralement. Nous avons donné un accessoire supplémentaire que nous avons utilisé dans le className pour définir le style du bouton.

Voici l'exemple complet :

import React, { ButtonHTMLAttributes } from 'react'
 
interface d'exportation ButtonProps étend ButtonHTMLAttributes {
 statut ? : 'primaire' | 'info' | 'danger'
}
 
Exporter la fonction par défaut Button(props : ButtonProps) {
 const { status, children, ...rest } = props
 revenir (
   
 )
}

C'est un excellent moyen de créer des composants internes réutilisables conformes à vos directives de style sans reconstruire des éléments HTML entiers ! Vous pouvez simplement remplacer des accessoires entiers tels que la définition du className en fonction du statut ou autoriser également la transmission de noms de classe supplémentaires.

import React, { ButtonHTMLAttributes } de 'react'
 
interface d'exportation ButtonProps étend ButtonHTMLAttributes {
 statut ? : 'primaire' | 'info' | 'danger'
}
 
Exporter la fonction par défaut Button(props : ButtonProps) {
 const { status, children, className, ...rest } = props
 revenir (
   
 )
}

Ici, nous prenons le prop className passé à notre élément Button et l'insérons de nouveau, avec un contrôle de sécurité dans le cas où le prop est undefined.

Conclusion

React est une bibliothèque extrêmement puissante, et il y a une bonne raison pour laquelle elle a rapidement gagné en popularité. Il vous offre un excellent ensemble d'outils pour créer des applications Web performantes et faciles à entretenir. Il est à la fois extrêmement flexible et très strict, ce qui peut être incroyablement utile si vous savez vous en servir. Ce ne sont là que quelques API qui méritent d'être notées et qui sont largement négligées. Essayez-les dans votre prochain projet !

Pour en savoir plus sur les dernières API React, les crochets, je vous recommande de lire useHooks(🐠). La Typescript Cheatsheet contient également d'excellentes informations sur les crochets React et Typescript.

Smashing Editorial(ks, vf, yk, il)






Source link