React v16.13.0

February 26, 2020 par Sunil Pai

Nous sortons aujourd’hui React 16.13.0. Cette version contient des correctifs et de nouveaux avertissements de dépréciation qui nous aident à préparer le terrain pour une future version majeure.

Nouveaux avertissements

Avertissement sur certaines mises à jour lors du rendu

Un composant React ne devrait pas causer d’effet de bord dans d’autres composants lors de son rendu.

Nous autorisons l’appel de setState lors du rendu, mais uniquement sur le même composant. Si, lors du rendu, vous appelez setState sur un autre composant, vous verrez désormais l’avertissement suivant :

Warning: Cannot update a component from inside the function body of a different component.

(« Avertissement : impossible de mettre à jour un composant depuis le corps de fonction d’un autre composant. »)

Cet avertissement vous aidera à détecter des bugs applicatifs résultant de modifications involontaires d’état. Dans les rares cas où vous voudriez effectivement modifier l’état d’un autre composant suite à votre rendu, vous pouvez enrober l’appel à setState au sein d’un useEffect.

Avertissement sur conflits de propriétés CSS

Lors de l’application dynamique d’un style contenant des versions concises et spécifiques de propriétés CSS, certaines combinaisons de mises à jour peuvent aboutir à des incohérences de style. Par exemple :

<div style={toggle ?
  { background: 'blue', backgroundColor: 'red' } :
  { backgroundColor: 'red' }
}>
  ...
</div>

Vous vous attendez alors sans doute à ce que la <div> ait un arrière-plan rouge, quelle que soit la valeur de toggle. Et pourtant, en faisant alterner la valeur de toggle entre true et false, la couleur d’arrière-plan démarre à red puis alterne entre transparent et blue, comme l’illustre cette démo.

React détecte désormais les conflits de propriétés CSS et émet un avertissement. Pour corriger ce problème, ne mélangez pas des syntaxes concises et spécifiques pour la même propriété CSS dans la prop style.

Avertissement sur certaines refs textuelles dépréciées

Les refs textuelles sont une ancienne API dont nous déconseillons l’emploi et qui sera dépréciée un jour :

<Button ref="myRef" />

(Ne pas confondre les refs textuelles avec les refs en général, qui restent elles totalement prises en charge.)

À l’avenir, nous fournirons un script automatisé (un “codemod”) pour migrer votre code afin qu’il ne recoure plus à des refs textuelles. Néanmoins, certains cas isolés ne peuvent être migrés automatiquement. Cette version ajoute un nouvel avertissement uniquement pour ces cas-là, avant que nous procédions à leur dépréciation.

Par exemple, cet avertissement sera déclenché si vous utilisez des refs textuelles en conjonction avec une approche à base de prop de rendu (render prop, NdT) :

class ClassWithRenderProp extends React.Component {
  componentDidMount() {
    doSomething(this.refs.myRef);
  }
  render() {
    return this.props.children();
  }
}

class ClassParent extends React.Component {
  render() {
    return (
      <ClassWithRenderProp>
        {() => <Button ref="myRef" />}
      </ClassWithRenderProp>
    );
  }
}

Ce type de code entraîne généralement des bugs. (Vous vous attendez peut-être à ce que la ref soit disponible dans ClassParent, mais au lieu de ça elle est placée sur ClassWithRenderProp).

Vous n’avez très probablement pas besoin de ce type de code. Si vous êtes pourtant volontairement dans un tel cas, utilisez plutôt React.createRef() :

class ClassWithRenderProp extends React.Component {
  myRef = React.createRef();
  componentDidMount() {
    doSomething(this.myRef.current);
  }
  render() {
    return this.props.children(this.myRef);
  }
}

class ClassParent extends React.Component {
  render() {
    return (
      <ClassWithRenderProp>
        {myRef => <Button ref={myRef} />}
      </ClassWithRenderProp>
    );
  }
}

Remarque

Pour voir cet avertissement, vous aurez besoin d’avoir installé babel-plugin-transform-react-jsx-self parmi vos plugins Babel. Il ne doit être activé que en mode développement.

Si vous utilisez Create React App ou le preset “react” avec Babel 7+, ce plugin est déjà installé par défaut.

Dépréciation de React.createFactory

React.createFactory est une ancienne fonction utilitaire servant à créer des éléments React. Cette version ajoute un avertissement de dépréciation à son sujet. Elle sera retirée dans une future version majeure.

Remplacez vos utilisations de React.createFactory par du JSX classique. Une autre approche consiste à copier-coller cet utilitaire qui tient sur une ligne, ou le publier sous forme de bibliothèque :

let createFactory = type => React.createElement.bind(null, type);

Ça fera exactement la même chose.

Dépréciation de ReactDOM.unstable_createPortal au profit de ReactDOM.createPortal

Lorsque nous avons sorti React 16, l’API createPortal est devenue officielle.

Cependant, nous avons continué à autoriser le recours à son nom temporaire unstable_createPortal afin de permettre à certaines bibliothèques l’ayant adopté de continuer à fonctionner. Nous déprécions désormais ce nom antérieur. Utilisez createPortal directement au lieu de unstable_createPortal. La signature est exactement la même.

Autres améliorations

Traces de piles des composants dans les avertissements de réhydratation

React ajoute des traces de piles de composants à ses avertissements de développement, ce qui permet aux développeurs d’isoler les bugs et de déboguer leurs programmes. Cette version ajoute ces traces de piles de composants à divers avertissements de développement qui n’en bénéficiaient pas jusqu’ici. Prenez par exemple cet avertissement de réhydratation dans les versions précédentes :

Capture d’écran d’un avertissement en console, qui indique juste la nature de la discordance de réhydratation : « Avertissement : le HTML renvoyé par le serveur aurait dû contenir un div correspondant dans le div. »

Bien qu’il signale une erreur dans le code, la cause de l’erreur n’est pas claire, ainsi que la conduite à adopter. Cette version ajoute une trace de pile de composants à l’avertissement, ce qui donne un affichage ressemblant à celui-ci :

Capture d’écran d’un avertissement en console, qui indique la nature de la discordance de réhydratation, mais avec la trace de pile de composants en plus : « Avertissement : le HTML renvoyé par le serveur aurait dû contenir un div correspondant dans le div (dans pages/index.js:4)... »

On clarifie ainsi l’emplacement et l’origine du problème, ce qui vous aide à repérer le bug et à le corriger plus vite.

Correctifs notables

Cette version contient par ailleurs quelques améliorations notables :

  • En mode strict de développement, React appelle les méthodes de cycle de vie deux fois pour éliminer au plus tôt les effets de bord involontaires. Cette version étend ce comportement à shouldComponentUpdate. Ça ne devrait guère affecter la plupart des bases de code, à moins que vous n’ayez des effets de bord dans shouldComponentUpdate. Pour y remédier, déplacez le code des effets de bord dans componentDidUpdate.
  • En mode strict de développement, les avertissements relatifs à l’utilisation de l’ancienne API de contexte n’incluaient pas de traces de piles de composant. Cette version les y ajoute.
  • onMouseEnter ne se déclenche plus sur les éléments <button> désactivés.
  • ReactDOM n’exportait plus version depuis la sortie de la v16. Cette version restaure l’export. Nous déconseillons de vous en servir dans votre logique applicative, mais ça peut être utile pour déboguer des problèmes dus à des incohérences de versions, ou versions multiples, de ReactDOM dans une même page.

Nous remercions tous les contributeurs qui nous ont aidé à repérer et corriger ces bugs et d’autres. Vous pouvez consulter le journal complet des modifications ci-après.

Installation

React

React v16.13.0 est disponible sur le référentiel npm.

Pour installer React 16 avec Yarn, exécutez :

yarn add react@^16.13.0 react-dom@^16.13.0

Pour installer React 16 avec npm, exécutez :

npm install --save react@^16.13.0 react-dom@^16.13.0

Nous fournissons aussi des builds de React sur un CDN :

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

Consultez la documentation pour des instructions d’installation détaillées.

Changelog

React

  • Avertir lorsqu’une ref textuelle est utilisée de façon incompatible avec un futur codemod (@lunaruan dans #17864)
  • Déprécier React.createFactory() (@trueadm dans #17878)

React DOM

  • Avertir lorsque des modifications à style risquent de causer des conflits inattendus (@sophiebits dans #14181 et #18002)
  • Avertir lorsqu’une fonction composant est mise à jour depuis la phase de rendu d’un autre composant (@acdlite dans #17099)
  • Déprécier unstable_createPortal (@trueadm dans #17880)
  • Corriger le déclenchement de onMouseEnter sur des boutons désactivés (@AlfredoGJ dans #17675)
  • Appeler shouldComponentUpdate deux fois en développement StrictMode (@bvaughn dans #17942)
  • Ajouter la propriété version à ReactDOM (@ealush dans #15780)
  • Ne pas appeler le toString() de dangerouslySetInnerHTML (@sebmarkbage dans #17773)
  • Afficher les traces de piles de composants dans davantage d’avertissements (@gaearon dans #17922 et #17586)

Mode concurrent (expérimental)

  • Avertir des utilisations problématiques de ReactDOM.createRoot() (@trueadm dans #17937)
  • Retirer les fonctions de rappel dans la signature de ReactDOM.createRoot() et ajouter des avertissements lorsque ces paramètres sont utilisés (@bvaughn dans #17916)
  • Ne pas grouper les travaux Idle/Offscreen avec d’autres travaux (@sebmarkbage dans #17456)
  • Ajuster les heuristiques d’occupation CPU de SuspenseList (@sebmarkbage dans #17455)
  • Ajouter les priorités manquantes du plugin d’événements (@trueadm dans #17914)
  • Corriger la valeur incorrecte à true de isPending pendant la transition depuis l’intérieur d’un événement input (@acdlite dans #17382)
  • Corriger la perte de mises à jour dans les composants enrobés par React.memo lorsqu’elles sont interrompues par des mises à jour à plus forte priorité (@acdlite dans #18091)
  • Ne pas avertir lors de la suspension au sein d’une priorité incorrecte (@gaearon dans #17971)
  • Corriger un bug au sein du repositionnement des mises à jour (@acdlite et @sebmarkbage dans #17560, #17510, #17483 et #17480)
Avez-vous trouvé cette page utile ?Modifier cette page