Composants communs (par exemple <div>)

Tous les composants natifs du navigateur, tels que <div>, prennent en charge des props et des é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 spécifiques à React sont prises en charge pour tous les composants natifs :

  • 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 ou un booléen, ou encore un tableau d’autres nœuds React). Elle 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 comme dans <div><span /></div>.

  • dangerouslySetInnerHTML : un objet de la forme { __html: '<p>du HTML</p>' } avec du HTML brut dans une chaîne de caractères. Il réécrit la propriété innerHTML du nœud DOM et affiche à l’intérieur le HTML fourni. Cette méthode doit être utilisée avec une extrême prudence ! Si le HTML fourni 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.

  • 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 calée sur l’élément 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 éléments qui ont à la fois des children et contentEditable={true} (lesquels 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 contentEditable.

  • suppressHydrationWarning : un booléen. Si vous utilisez le rendu côté serveur, il y a normalement un avertissement lorsque les rendus côté serveur et côté client produisent un contenu différent. Dans certains rares cas (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 d’incohérence d’attributs ou de contenu pour cet élément. Ça ne fonctionne qu’à un seul niveau de profondeur, et c’est conçu comme une échappatoire. N’en n’abusez pas. Apprenez-en davantage sur la suppression des erreurs d’hydratation.

  • style : un objet contenant des styles CSS, par exemple { fontWeight: 'bold', margin: 20 }. À l’image de la propriété style du DOM, les noms des propriétés CSS doivent être écrites en camelCase, comme fontWeight au lieu de font-weight. Vous pouvez passer des valeurs sous forme de chaîne de caractères ou de nombre. Si vous utilisez 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 vous conseillons de n’utiliser style que pour les styles dynamiques, pour lesquels vous ne connaissez pas les valeurs de style à l’avance. Dans les autres cas, il est bien plus performant d’utiliser des classes CSS avec className. Apprenez-en davantage sur className et style.

Ces props standard du DOM sont également prises en charge pour tous les composants natifs :

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 retiré.

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 sont propagés le long du DOM :

Ces événements sont déclenchés pour les éléments <details>. Contrairement aux événements du navigateur, ceux en React sont propagés le long du 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 sont propagés le long du DOM :

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

Limitations

  • Vous ne pouvez pas passer à la fois children et dangerouslySetInnerHTML.
  • Certains événements (tels que onAbort et onLoad) ne sont pas propagés le long du DOM par le navigateur, mais le sont 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> sera ajouté à l’écran, React appellera votre fonction ref avec le node DOM comme argument. Quand ce nœud DOM <div> sera retiré, React apppellera votre fonction ref avec null.

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

Paramètres

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

Valeur renvoyée

La fonction ref ne renvoie rien.


Objet d’événement React

Vos gestionnaires d’événements recevront un objet d’événement React. On parle aussi parfois « d’événement synthétique » React.

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

Il respecte le même standard que les événements DOM natifs, mais corrige certaines incohérences d’implémentation d’un navigateurs à l’autr.

Certains événements React ne correspondent pas directement aux événements natifs des navigateurs. Dans onMouseLeave par exemple, e.nativeEvent référence 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, vous le trouverez dans dans e.nativeEvent.

Propriétés

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

  • bubbles : un booléen. Il indique si l’événement se propage le long 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 auquel le gestionnaire d’événement est attaché 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 dans 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 descendant lointain).
  • timeStamp : un nombre. Il indique le moment où l’événement a été déclenché.

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

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

Méthodes

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

  • preventDefault() : empêche l’action par défaut du navigateur pour cet événement.
  • stopPropagation() : interrompt la propagation de cet événement le long de l’arbre React.

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

  • isDefaultPrevented() : renvoie une valeur booléenne indiquant si preventDefault a été appelée.
  • isPropagationStopped() : renvoie une valeur booléenne indiquant si stopPropagation a été appelée.
  • persist() : inutile pour 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() : inutile pour 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 différer du e.nativeEvent.currentTarget sous-jacent. Pour les événements simulés, e.type (type de l’événement React) peut aussi 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


Gestionnaire CompositionEvent

Un type de gestionnaire d’événement pour les événements des systèmes de composition de texte (IME pour Input Method Editor, NdT).

<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 HTML de glisser-déposer.

<>
<div
draggable={true}
onDragStart={e => console.log('onDragStart')}
onDragEnd={e => console.log('onDragEnd')}
>
Source pour le glissement
</div>

<div
onDragEnter={e => console.log('onDragEnter')}
onDragLeave={e => console.log('onDragLeave')}
onDragOver={e => { e.preventDefault(); console.log('onDragOver'); }}
onDrop={e => console.log('onDrop')}
>
Cible pour le dépôt
</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 liés au 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 liés à 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 liés aux pointeurs.

<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 transitions 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 (molette de souris).

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

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 n’impose aucune façon particulière d’ajouter des fichiers CSS. Dans les cas les plus simples, vous ajouterez une balise <link> dans votre HTML. Si vous utilisez un outil de build ou un framework, consultez sa documentation pour connaître la façon d’ajouter un fichier CSS à votre projet.

Parfois, les valeurs de style que vous souhaitez utiliser dépendent de vos données. 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 vous conseillons de n’utiliser l’attribut style que 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 conditionnellement plusieurs classes CSS ?

Pour conditionner l’application de classes CSS, vous devez produire vous-même la chaîne de caractères className en utilisant 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 utile 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

Vous aurez parfois besoin de récupérer le nœud DOM du navigateur associé à une balise en JSX. Si par exemple vous voulez activer 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, déclarez une ref et passez-la à l’attribut ref de cette balise :

import { useRef } from 'react';

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

React référencera le nœud DOM depuis la propriété inputRef.current une fois le DOM mis à jour.

import { useRef } from 'react';

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

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

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

Apprenez-en davantage sur la manipulation du DOM avec les refs et découvrez d’autres exemples.

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


Définir le HTML interne (mais c’est risqué)

Vous pouvez passer une chaîne de caractères contenant du HTML brut à un élément comme suit :

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

C’est dangereux. Comme avec la propriété innerHTML du DOM, 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 qui convertit du Markdown en HTML, que vous êtes sûr·e 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 fiable UNIQUEMENT parce que le HTML généré
  // n’est affiché qu’à l’utilisateur qui l’a saisi,
  // 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} />;
}

L’objet {__html} est censé être produit le plus près possible de la génération effective du HTML, comme le fait l’exemple précédent dans la fonction renderMarkdownToHTML. Ça garantit que tous les morceaux de HTML brut dans votre code sont explicitement identifiés comme tels, et que seules les variables dans le contenu desquelles vous anticipez la présence de HTML sont passées à dangerouslySetInnerHTML. Nous vous déconseillons de créer ces objets à la volée comme dans <div dangerouslySetInnerHTML={{__html: markup}} />.

Pour comprendre pourquoi l’injection d’un contenu HTML quelconque est dangereuse, remplacez le code plus haut par celui-ci :

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

export default function MarkdownPreview() {
// 🔴 FAILLE DE SÉCURITÉ : passage d’une saisie non fiable à 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 à l’utilisateur ou effectuer certaines actions en son nom. Utilisez seulement dangerouslySetInnerHTML avec des données de confiance, dûment assainies.


Gérer des événements liés à la souris

Cet exemple montre quelques événements liés à la souris courants et la chronologie de leurs déclenchements.

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 liés aux pointeurs courants et permet de suivre la chronologie de leurs déclenchements.

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 se propagent le long du DOM. Vous pouvez utiliser currentTarget et relatedTarget pour savoir si les événements de prise de focus ou de perte de focus 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 événements liés au clavier

Cet exemple montre quelques événements liés au clavier courants et la chronologie de leurs déclenchements.

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>
  );
}