Composants communs (par exemple <div>)

Tous les composants intégrés du navigateur, tel que <div>, prennent en charge des props et événements communs.


Référence

Composants communs (par exemple <div>)

<div className="wrapper">Quelque chose</div>

Voir d’autres exemples plus bas.

Props

Ces props React particulières sont supportées pour tous les composants intégrés :

  • children : un nœud React (un élément, une chaîne de caractères, un nombre, un portail, un nœud vide comme null, undefined et les booléns ou un tableau d’autres nœuds React). Ça spécifie le contenu à l’intérieur d’un composant. Lorsque vous utilisez du JSX, vous spécifiez généralement la prop children de manière implicite en imbriquant les balises telles que <div><span /></div>.

  • dangerouslySetInnerHTML : un objet de la forme { __html: '<p>some html</p>' } avec du HTML brut dans une chaîne de caractères. Il surcharge la propriété innerHTML du nœud du DOM et affiche à l’intérieur le HTML donné. Cette méthode doit être utilisée avec une extrême prudence ! Si le HTML contenu n’est pas fiable (par exemple s’il est basé sur des données de l’utilisateur), vous risquez d’introduire une vulnérabilité XSS. Apprenez-en davantage sur dangerouslySetInnerHTML ici.

  • ref : un objet ref provenant de useRef, de createRef, d’une fonction de rappel ref ou d’une chaîne de caractères pour les refs historiques. Votre ref sera rempli par l’élément du DOM pour ce nœud. Apprenez-en davantage sur la manipulation du DOM avec les refs.

  • suppressContentEditableWarning : un booléen. S’il est à true, supprime l’avertissement que React affiche pour les élements qui ont à la fois des children et contentEditable={true} (qui ne fonctionnent normalement pas ensemble). Vous pouvez l’utiliser si vous construisez une bibliothèque de champ de saisie qui gère manuellement le contenu du contentEditable.

  • suppressHydrationWarning : un booléen. Si vous utilisez le rendu côté serveur, il y a normalement un avertissement lorsque le serveur et le client font le rendu d’un contenu différent. Dans certains cas rares (comme avec les horodatages), il est très compliqué, voire impossible, de garantir une correspondance exacte. Si vous définissez suppressHydrationWarning à true, React ne vous alertera plus en cas de non-concordance entre les attributs et le contenu de cet élément. Ça ne fonctionne que sur un seul niveau de profondeur et est destiné à servir d’échappatoire. N’en n’abusez pas. Apprenez-en davantage sur la suppression des errors d’hydratation ici.

  • style : un objet contenant des styles CSS, par exemple { fontWeight: 'bold', margin: 20 }. À l’image de la propriété du DOM style, les noms des propriétés CSS doivent être écrites en camelCase, par exemple fontWeight plutôt que font-weight. Vous pouvez passer des valeurs sous forme de chaîne de caractères ou de nombre. Si vous donnez un nombre, tel que width: 100, React ajoutera automatiquement px (« pixels ») à la valeur, à moins qu’il ne s’agisse d’une propriété sans unité. Nous recommandons d’utiliser style uniquement pour les styles dynamiques pour lesquelles vous ne connaissez pas les valeurs de style à l’avance. Dans les autres cas, utiliser des classes CSS avec className est bien plus efficace. Apprenez-en davantage sur className et style ici.

Ces props standards du DOM sont également supportés pour tous les composants intégrés :

Vous pouvez également passer des attributs personnalisés comme props, par exemple mycustomprop="uneValeur". Ça peut être utile à l’intégration de bibliothèques tierces. Le nom de l’attribut personnalisé doit être en minuscules et ne doit pas commencer par on. La valeur sera convertie en chaîne de caractères. Si vous passez null ou undefined, l’attribut personnalisé sera supprimé.

Ces événements sont déclenchés pour les éléments <form> :

Ces événements sont déclenchés pour les éléments <dialog>.Contrairement aux événements du navigateur, ceux en React remontent dans le DOM :

Ces événements sont déclenchés pour les éléments <details>. Contrairement aux événements du navigateur, ceux en React remontent dans le DOM :

Ces événements sont déclenchés pour les éléments <img>, <iframe>, <object>, <embed>, <link>, et <image> SVG. Contrairement aux événements du navigateur, ceux en React remontent dans le DOM :

Ces événements sont déclenchés pour les ressources comme <audio> et <video>. Contrairement aux événements du navigateur, ceux en React remontent dans le DOM :

Limitations

  • Vous ne pouvez pas passer à la fois children et dangerouslySetInnerHTML en même temps.
  • Certains événements (tels que onAbort et onLoad) ne remontent pas dans le navigateur mais le font en React.

La fonction de rappel ref

Au lieu d’un objet ref (tel que celui renvoyé par useRef), vous pouvez passer une fonction à l’attribut ref.

<div ref={(node) => console.log(node)} />

Voir un exemple d’utilisation de la fonction de rappel ref.

Quand le nœud DOM <div> est ajouté à l’écran, React appelle votre fonction ref avec le node DOM comme argument. Quand ce nœud DOM <div> est enlevé, React apppelle votre fonction ref avec null.

React appellera aussi votre fonction ref à chaque fois que vous passez une fonction ref différente. Dans l’exemple plus hat, (node) => { ... } est une fonction différente à chaque rendu. Lorsque votre composant refait un rendu, la fonction précédente sera appelée avec l’argument null, et la prochaine fonction sera appelée avec le nœud DOM.

Paramètres

  • node : un nœud DOM ou null. React vous donnera le nœud DOM lors que la ref sera attachée, et null lorsqu’elle sera détachée. À moins de passer la même référence de fonction pour ref à chaque rendu, la fonction de retour sera détachée et réattachée pendant chaque nouveau rendu du composant.

Valeur renvoyée

La fonction ref ne renvoie rien.


Objet d’événement React

Votre gestionnaire d’événement reçoit un objet d’événement React. C’est également connu sous le nom d’« événement synthétique ».

<button onClick={e => {
console.log(e); // Objet événement React
}} />

Il est conforme aux même standard que les événements DOM sous-jacents, mais corrige certaines incohérences des navigateurs.

Certains événements React ne correspondent pas directement aux événements natifs des navigateurs. Par exemple, pour onMouseLeave, e.nativeEvent indiquera un événement mouseout. La correspondance spécifique ne fait pas partie de l’API publique et pourrait changer à l’avenir. Si, pour certaines raisons, vous avez besoin de l’événement sous-jacent du navigateur, allez le chercher depuis e.nativeEvent.

Propriétés

Les objets d’événements React implémentent certaines propriétés standard des Event :

  • bubbles : un booléen. Il indique si l’événement remonte au niveau du DOM.
  • cancelable : un booléen. Il indique si l’événement peut être annulé.
  • currentTarget : un nœud DOM. Il renvoie le nœud sur lequel est attaché le gestionnaire dans l’arbre React.
  • defaultPrevented : un booléen. Il indique si la fonction preventDefault a été appelée.
  • eventPhase : un nombre. Il indique la phase sur laquelle se situe actuellement l’événement.
  • isTrusted : un booléen. Il indique si l’événement a été initié par l’utilisateur.
  • target : un nœud DOM. Il renvoie le nœud sur lequel l’événement a été déclenché (qui peut être un enfant lointain).
  • timeStamp : un nombre. Il indique le moment où l’événement a été déclenché.

Les objets d’événements React propose également ces propriétés :

  • nativeEvent : un Event DOM. Il s’agit de l’objet d’événement du navigateur originel.

Méthodes

Les objets d’événements React implémentent certaines méthodes standards Event :

  • preventDefault() : empêche l’action par défaut du navigateur pour l’événement.
  • stopPropagation() : arrête la propagation de l’événement au sein de l’arbre React.

Les objets d’événements React propose également ces méthodes :

  • isDefaultPrevented() : renvoie une valeur booléenne indiquant si preventDefault a été appeléee.
  • isPropagationStopped() : renvoie une valeur booléenne indiquant si stopPropagation a été appelée.
  • persist() : elle n’est pas utilisée avec React DOM. Avec React Native, vous pouvez l’appeler pour lire les propriétés de l’événement après son exécution.
  • isPersistent() : elle n’est pas utilisée avec React DOM. Avec React Native, indique si persist a été appelée.

Limitations

  • Les valeurs de currentTarget, eventPhase, target et type réflètent les valeurs attendues par votre code React. Sous le capot, React attache les gestionnaires d’événements à la racine, mais ce n’est pas reflété par les objets d’événements React. Par exemple, e.currentTarget peut ne pas être le même que le e.nativeEvent.currentTarget sous-javent. Pour les événements polyfillés, e.type (type de l’événement React) peut différer de e.nativeEvent.type (type sous-jacent).

Gestionnaire AnimationEvent

Un type de gestionnaire d’événement pour les événements des animations CSS .

<div
onAnimationStart={e => console.log('onAnimationStart')}
onAnimationIteration={e => console.log('onAnimationIteration')}
onAnimationEnd={e => console.log('onAnimationEnd')}
/>

Paramètres


Gestionnaire ClipboardEvent

Un type de gestionnaire d’événement pour les événements de l’API Clipboard.

<input
onCopy={e => console.log('onCopy')}
onCut={e => console.log('onCut')}
onPaste={e => console.log('onPaste')}
/>

Paramètres


Gestionaire CompositionEvent

Un type de gestionnaire d’événement pour les événements des méthodes des éditeurs de saisie (IME).

<input
onCompositionStart={e => console.log('onCompositionStart')}
onCompositionUpdate={e => console.log('onCompositionUpdate')}
onCompositionEnd={e => console.log('onCompositionEnd')}
/>

Paramètres


Gestionnaire DragEvent

Un type de gestionnaire d’événement pour les événements de l’API Drag and Drop du HTML.

<>
<div
draggable={true}
onDragStart={e => console.log('onDragStart')}
onDragEnd={e => console.log('onDragEnd')}
>
Drag source
</div>

<div
onDragEnter={e => console.log('onDragEnter')}
onDragLeave={e => console.log('onDragLeave')}
onDragOver={e => { e.preventDefault(); console.log('onDragOver'); }}
onDrop={e => console.log('onDrop')}
>
Drop cible
</div>
</>

Paramètres


Gestionnaire FocusEvent

Un type de gestionnaire d’événement pour les événements de focus.

<input
onFocus={e => console.log('onFocus')}
onBlur={e => console.log('onBlur')}
/>

Voir un exemple.

Paramètres


Gestionnaire Event

Un gestionnaire d’événement pour les événements génériques.

Paramètres


Gestionnaire InputEvent

Un type de gestionnaire d’événement pour les événements onBeforeInput.

<input onBeforeInput={e => console.log('onBeforeInput')} />

Paramètres


Gestionnaire KeyboardEvent

Un type de gestionnaire d’événement pour les événements du clavier.

<input
onKeyDown={e => console.log('onKeyDown')}
onKeyUp={e => console.log('onKeyUp')}
/>

Voir un exemple.

Paramètres


Gestionnaire MouseEvent

Un type de gestionnaire d’événement pour les événements de la souris.

<div
onClick={e => console.log('onClick')}
onMouseEnter={e => console.log('onMouseEnter')}
onMouseOver={e => console.log('onMouseOver')}
onMouseDown={e => console.log('onMouseDown')}
onMouseUp={e => console.log('onMouseUp')}
onMouseLeave={e => console.log('onMouseLeave')}
/>

Voir un exemple.

Paramètres


Gestionnaire PointerEvent

Un type de gestionnaire d’événement pour les événements de pointeur.

<div
onPointerEnter={e => console.log('onPointerEnter')}
onPointerMove={e => console.log('onPointerMove')}
onPointerDown={e => console.log('onPointerDown')}
onPointerUp={e => console.log('onPointerUp')}
onPointerLeave={e => console.log('onPointerLeave')}
/>

Voir un exemple.

Paramètres


Gestionnaire TouchEvent

Un type de gestionnaire d’événement pour les événements tactiles.

<div
onTouchStart={e => console.log('onTouchStart')}
onTouchMove={e => console.log('onTouchMove')}
onTouchEnd={e => console.log('onTouchEnd')}
onTouchCancel={e => console.log('onTouchCancel')}
/>

Paramètres


Gestionnaire TransitionEvent

Un type de gestionnaire d’événement pour les événements de transition CSS.

<div
onTransitionEnd={e => console.log('onTransitionEnd')}
/>

Paramètres


Gestionnaire UIEvent

Un type de gestionnaire d’événement pour les événements génériques de l’interface utilisateur.

<div
onScroll={e => console.log('onScroll')}
/>

Paramètres


Gestionnaire WheelEvent

Un type de gestionnaire d’événement pour les événements onWheel.

<div
onScroll={e => console.log('onScroll')}
/>

Paramètres


Utilisation

Appliquer les styles CSS

En React, vous spécifiez une classe CSS avec className. Ça fonctionne comme l’attribut HTML class :

<img className="avatar" />

Vous écrivez ensuite vos règles CSS dans un fichier CSS séparé :

/* Dans votre CSS */
.avatar {
border-radius: 50%;
}

React ne prescrit pas la façon dont vous ajoutez des fichiers CSS. Dans les cas les plus simples, vous ajouterez une balise <link> dans votre HTML. Si vous utilisez un outil de construction ou un framework, consultez sa documentation pour connaître la façon d’ajouter un fichier CSS à votre projet.

Parfois, les valeurs de style dépendent de la donnée. Utilisez l’attribut style pour passer certains styles dynamiquement :

<img
className="avatar"
style={{
width: user.imageSize,
height: user.imageSize
}}
/>

Dans l’exemple ci-dessus, style={{}} n’est pas une syntaxe particulière, mais un objet classique {} à l’intérieur des accolades JSX style={ }. Nous recommandons d’utiliser l’attribut style uniquement si vos styles dépendent de variables JavaScript.

export default function Avatar({ user }) {
  return (
    <img
      src={user.imageUrl}
      alt={'Photo de ' + user.name}
      className="avatar"
      style={{
        width: user.imageSize,
        height: user.imageSize
      }}
    />
  );
}

En détail

Comment appliquer plusieurs classes CSS sous conditions ?

Pour conditionner l’application de classes CSS, vous devez produire vous-même la chaîne de caractères className en utilisant le JavaScript.

Par exemple, className={'row ' + (isSelected ? 'selected': '')} produira soit className="row", soit className="row selected", selon que isSelected est à true ou non.

Pour faciliter la lecture, vous pouvez utiliser une petite bibliothèque telle que classnames :

import cn from 'classnames';

function Row({ isSelected }) {
return (
<div className={cn('row', isSelected && 'selected')}>
...
</div>
);
}

C’est particulièrement pratique si vous avez plusieurs classes conditionnelles :

import cn from 'classnames';

function Row({ isSelected, size }) {
return (
<div className={cn('row', {
selected: isSelected,
large: size === 'large',
small: size === 'small',
})}>
...
</div>
);
}

Manipuler un nœud DOM avec une ref

Parfois, vous aurez besoin de récupérer le nœud DOM du navigateur associé à une balise en JSX. Par exemple, si vous voulez mettre le focus sur un <input> après qu’un bouton a été cliqué, vous aurez besoin d’appeler focus() sur le nœud DOM <input> du navigateur.

Pour obtenir le nœud DOM du navigateur correspondant à une balise, il faut déclarer une ref et la passer à l’attribut ref de cette balise :

import { useRef } from 'react';

export default function Form() {
const inputRef = useRef(null);
// ...
return (
<input ref={inputRef} />
// ...

React placera le nœud DOM dans la propriété inputRef.current une fois qu’il sera rendu à l’écran.

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Placer le focus sur le champ
      </button>
    </>
  );
}

Apprenez-en davantage à propos de la manipulatiion du DOM avec les refs et découvrir d’autres exemples.

Pour des utilisations plus avancées, l’attribut ref accepte églament une fonction de rappel.


Définir le HTML interne de façon risquée

Vous pouvez passer une chaîne de caractère contenant du HTML brut à un élément de cette façon :

const markup = { __html: '<p>du HTML brut</p>' };
return <div dangerouslySetInnerHTML={markup} />;

C’est dangereux. Comme pour la propriété du DOM innerHTML, vous devez faire preuve d’une extrême prudence ! À moins que le balisage ne provienne d’une source parfaitement fiable, il est facile d’introduire une vulnérabilité XSS de cette façon.

Par exemple, si vous utilisez une bibliothèque de Markdown qui convertit le Markdown en HTML, que vous êtes sûr que son parser ne contient pas de bug et que l’utilisateur ne voit que ses propres données, vous pouvez afficher le HTML généré de cette façon :

import { Remarkable } from 'remarkable';

const md = new Remarkable();

function renderMarkdownToHTML(markdown) {
  // C'est sûr UNIQUEMENT parce que le HTML généré
  // est affiché à l'utilisateur, et parce que
  // vous avez confiance dans le fait que ce
  // parser de Markdown ne contient pas de bugs.
  const renderedHTML = md.render(markdown);
  return {__html: renderedHTML};
}

export default function MarkdownPreview({ markdown }) {
  const markup = renderMarkdownToHTML(markdown);
  return <div dangerouslySetInnerHTML={markup} />;
}

Pour comprendre pourquoi le rendu d’un HTML arbitraire est dangereux, remplacez le code plus haut par celui-ci :

const post = {
// Imaginez que ce contenu est stocké en base de données.
content: `<img src="" onerror='alert("vous avez été hacké")'>`
};

export default function MarkdownPreview() {
// 🔴 FAILLE DE SÉCURITÉ : passer une saisie non fiable to dangerouslySetInnerHTML
const markup = { __html: post.content };
return <div dangerouslySetInnerHTML={markup} />;
}

Le code intégré dans le HTML sera exécuté. Un hacker pourrait utiliser cette faille de sécurité pour voler des informations de l’utilisateur ou effectuer certaines actions en son nom. Utilisez seulement dangerouslySetInnerHTML avec des données de confiance et assainies.


Gérer des événements de la souris

Cet exemple montre quelques événements de souris courants et quand ils sont déclenchés.

export default function MouseExample() {
  return (
    <div
      onMouseEnter={e => console.log('onMouseEnter (parent)')}
      onMouseLeave={e => console.log('onMouseLeave (parent)')}
    >
      <button
        onClick={e => console.log('onClick (premier bouton)')}
        onMouseDown={e => console.log('onMouseDown (premier bouton)')}
        onMouseEnter={e => console.log('onMouseEnter (premier bouton)')}
        onMouseLeave={e => console.log('onMouseLeave (premier bouton)')}
        onMouseOver={e => console.log('onMouseOver (premier bouton)')}
        onMouseUp={e => console.log('onMouseUp (premier bouton)')}
      >
        Premier bouton
      </button>
      <button
        onClick={e => console.log('onClick (deuxième bouton)')}
        onMouseDown={e => console.log('onMouseDown (deuxième bouton)')}
        onMouseEnter={e => console.log('onMouseEnter (deuxième bouton)')}
        onMouseLeave={e => console.log('onMouseLeave (deuxième bouton)')}
        onMouseOver={e => console.log('onMouseOver (deuxième bouton)')}
        onMouseUp={e => console.log('onMouseUp (deuxième bouton)')}
      >
        Deuxième bouton
      </button>
    </div>
  );
}


Gérer des événements du pointeur

Cet exemple montre quelques événements de pointeur courants et quand ils sont déclenchés.

export default function PointerExample() {
  return (
    <div
      onPointerEnter={e => console.log('onPointerEnter (parent)')}
      onPointerLeave={e => console.log('onPointerLeave (parent)')}
      style={{ padding: 20, backgroundColor: '#ddd' }}
    >
      <div
        onPointerDown={e => console.log('onPointerDown (premier enfant)')}
        onPointerEnter={e => console.log('onPointerEnter (premier enfant)')}
        onPointerLeave={e => console.log('onPointerLeave (premier enfant)')}
        onPointerMove={e => console.log('onPointerMove (premier enfant)')}
        onPointerUp={e => console.log('onPointerUp (premier enfant)')}
        style={{ padding: 20, backgroundColor: 'lightyellow' }}
      >
        Premier enfant
      </div>
      <div
        onPointerDown={e => console.log('onPointerDown (deuxième enfant)')}
        onPointerEnter={e => console.log('onPointerEnter (deuxième enfant)')}
        onPointerLeave={e => console.log('onPointerLeave (deuxième enfant)')}
        onPointerMove={e => console.log('onPointerMove (deuxième enfant)')}
        onPointerUp={e => console.log('onPointerUp (deuxième enfant)')}
        style={{ padding: 20, backgroundColor: 'lightblue' }}
      >
        Deuxième enfant
      </div>
    </div>
  );
}


Gérer les événéments de focus

Avec React, les événements de focus remontent dans le DOM. Vous pouvez utiliser currentTarget et relatedTarget pour différencier si les événements de focus ou de blur proviennent de l’extérieur de l’élément parent. L’exemple montre comment détecter le focus d’un enfant, celui de l’élément parent et comment détecter l’entrée ou la sortie du focus sur l’ensemble du sous-arbre.

export default function FocusExample() {
  return (
    <div
      tabIndex={1}
      onFocus={(e) => {
        if (e.currentTarget === e.target) {
          console.log('focus sur le parent');
        } else {
          console.log("focus sur l'enfant", e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // N'est pas déclenché quand on passe d'un enfant à l'autre 
          console.log('focus entré au niveau du parent');
        }
      }}
      onBlur={(e) => {
        if (e.currentTarget === e.target) {
          console.log('Perte du focus par le parent');
        } else {
          console.log("Perte du focus par l'enfant", e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // N'est pas déclenché quand on passe d'un enfant à l'autre
          console.log('Le focus quitte le parent');
        }
      }}
    >
      <label>
        Prénom :
        <input name="firstName" />
      </label>
      <label>
        Nom :
        <input name="lastName" />
      </label>
    </div>
  );
}


Gérer les évenements du clavier

Cet exemple montre quelques événements du clavier courants et quand ils sont déclenchés.

export default function KeyboardExample() {
  return (
    <label>
      Prénom :
      <input
        name="firstName"
        onKeyDown={e => console.log('onKeyDown:', e.key, e.code)}
        onKeyUp={e => console.log('onKeyUp:', e.key, e.code)}
      />
    </label>
  );
}