React: React Fire : moderniser React DOM

Créé le 31 août 2018  ·  227Commentaires  ·  Source: facebook/react


Pour le dernier statut, consultez une mise à jour du 5 juin 2019 : https://github.com/facebook/react/issues/13525#issuecomment -499196939


Cette année, l'équipe React s'est principalement concentrée sur les améliorations fondamentales de React .

Alors que ce travail touche à sa fin, nous commençons à réfléchir à ce à quoi devraient ressembler les prochaines versions majeures de React DOM. Il existe de nombreux problèmes connus , et certains d'entre eux sont difficiles ou impossibles à résoudre sans modifications internes plus importantes.

Nous voulons annuler les erreurs passées qui ont causé d'innombrables correctifs de suivi et créé beaucoup de dette technique. Nous voulons également supprimer une partie de l'abstraction dans le système d'événements qui a été pratiquement intacte depuis les premiers jours de React, et qui est une source de complexité et de taille de bundle.

Nous appelons cet effort "React Fire".

🔥 Réagissez au feu

React Fire est un effort pour moderniser React DOM. Notre objectif est de mieux aligner React sur le fonctionnement du DOM, de revoir certaines décisions passées controversées qui ont conduit à des problèmes et de rendre React plus petit et plus rapide.

Nous voulons expédier cet ensemble de modifications dans une future version majeure de React, car certaines d'entre elles seront malheureusement en panne. Néanmoins, nous pensons qu'ils en valent la peine. Et nous avons plus de 50 000 composants sur Facebook pour rester honnêtes sur notre stratégie de migration. Nous ne pouvons pas nous permettre de réécrire le code du produit, à l'exception de quelques correctifs ciblés ou de codemods automatisés.

Stratégie

Il y a quelques éléments différents qui composent notre plan actuel. Nous pourrions ajouter ou supprimer quelque chose, mais voici la réflexion jusqu'à présent :

  • Arrêtez de refléter les valeurs d'entrée dans l'attribut value (https://github.com/facebook/react/issues/11896). Cela a été initialement ajouté dans React 15.2.0 via https://github.com/facebook/react/pull/6406. Il a été très souvent demandé parce que le modèle conceptuel du DOM des gens est que le value qu'ils voient dans l'inspecteur DOM doit correspondre à l'attribut JSX value . Mais ce n'est pas ainsi que fonctionne le DOM. Lorsque vous tapez dans un champ, le navigateur ne met pas à jour l'attribut value . React ne devrait pas le faire non plus. Il s'est avéré que ce changement, bien que probablement utile pour certains codes reposant sur des sélecteurs CSS, a provoqué une cascade de bogues, dont certains n'ont pas encore été corrigés à ce jour. Certaines des retombées de ce changement incluent : https://github.com/facebook/react/issues/7179 , https://github.com/facebook/react/issues/8395 , https://github.com/facebook /react/issues/7328 , https://github.com/facebook/react/issues/7233 , https://github.com/facebook/react/issues/11881 , https://github.com/facebook/react /issues/7253 , https://github.com/facebook/react/pull/9584 , https://github.com/facebook/react/pull/9806 , https://github.com/facebook/react/pull /9714 ​​, https://github.com/facebook/react/pull/11534 , https://github.com/facebook/react/pull/11746 , https://github.com/facebook/react/pull/12925 . À ce stade, cela ne vaut clairement pas la peine de continuer à lutter contre le navigateur, et nous devrions revenir en arrière. La partie positive de ce voyage est que grâce au travail inlassable de nos contributeurs DOM ( @nhunzaker , @aweary , @jquense et @philipp-spiess ), nous avons maintenant des montages de test DOM détaillés qui nous aideront à éviter les régressions.

  • Joignez les événements à la racine de React plutôt qu'au document (https://github.com/facebook/react/issues/2043). Attacher des gestionnaires d'événements au document devient un problème lors de l'intégration d'applications React dans des systèmes plus importants. L'éditeur Atom a été l'un des premiers cas qui s'est heurté à cela. Tout grand site Web développe également éventuellement des cas périphériques très complexes liés à stopPropagation interagissant avec du code non-React ou à travers des racines React (https://github.com/facebook/react/issues/8693, https://github .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). Nous voudrons également attacher des événements avec impatience à chaque racine afin de pouvoir effectuer moins de vérifications d'exécution lors des mises à jour.

  • Migrez de onChange vers onInput et ne le polyfillez pas pour les composants non contrôlés (https://github.com/facebook/react/issues/9657). Voir le problème lié pour un plan détaillé. Il est déroutant que React utilise un nom d'événement différent pour ce qu'on appelle l'événement input dans le DOM. Bien que nous évitions généralement de faire de gros changements comme celui-ci sans avantage significatif, dans ce cas, nous voulons également modifier le comportement pour supprimer une certaine complexité qui n'est nécessaire que pour les cas extrêmes comme la mutation des entrées contrôlées. Il est donc logique de faire ces deux changements ensemble et d'utiliser cela comme une opportunité pour que onInput et onChange fonctionnent exactement comme les événements DOM fonctionnent pour les composants non contrôlés.

  • Simplifiez considérablement le système d'événements (https://github.com/facebook/react/issues/4751). Le système d'événements actuel a à peine changé depuis sa mise en œuvre initiale en 2013. Il est réutilisé dans React DOM et React Native, il est donc inutilement abstrait. La plupart des polyfills qu'il fournit ne sont pas nécessaires pour les navigateurs modernes, et certains d'entre eux créent plus de problèmes qu'ils n'en résolvent. Il représente également une partie importante de la taille du bundle React DOM. Nous n'avons pas de plan très précis ici, mais nous allons probablement bifurquer complètement le système d'événements, puis voir à quel point nous pouvons le rendre minimal si nous nous en tenons plus près de ce que le DOM nous donne. Il est plausible que nous nous débarrassions complètement des événements synthétiques. Nous devrions arrêter les événements bouillonnants comme les événements médiatiques qui ne bouillonnent pas dans le DOM et n'ont pas de bonne raison de bouillonner. Nous souhaitons conserver certaines fonctionnalités spécifiques à React, telles que le bouillonnement à travers les portails, mais nous essaierons de le faire par des moyens plus simples (par exemple, redistribuer l'événement). Les événements passifs en feront probablement partie.

  • classNameclass (https://github.com/facebook/react/issues/4331, voir aussi https://github.com/facebook/react/issues/13525#issuecomment- 417818906 ci-dessous). Cela a été proposé un nombre incalculable de fois. Nous autorisons déjà le passage class au nœud DOM dans React 16. La confusion que cela crée ne vaut pas les limitations de syntaxe contre lesquelles il essaie de se protéger. Nous ne ferions pas ce changement par lui-même, mais combiné avec tout ce qui précède, il a du sens. Notez que nous ne pouvons pas autoriser les deux sans avertissement, car cela rend la gestion très difficile pour un écosystème de composants. Chaque composant devrait apprendre à gérer les deux correctement, et il y a un risque qu'ils entrent en conflit. Étant donné que de nombreux composants traitent className (par exemple en y ajoutant), il est trop sujet aux erreurs.

Compromis

  • Nous ne pouvons pas apporter certaines de ces modifications si nous souhaitons continuer à exposer les API privées actuelles du système d'événements React pour des projets tels que React Native Web. Cependant, React Native Web aura besoin d'une stratégie différente, car React Fabric déplacera probablement une plus grande partie du système de répondeur vers le côté natif.

  • Nous devrons peut-être abandonner la compatibilité avec certains navigateurs plus anciens et/ou exiger plus de polyfills autonomes pour eux. Nous nous soucions toujours de la prise en charge d'IE11, mais il est possible que nous n'essayions pas de lisser certaines des différences de navigateur existantes, ce qui est la position adoptée par de nombreuses bibliothèques d'interface utilisateur modernes.

Plan de déploiement

A ce stade, le projet est très exploratoire. Nous ne savons pas avec certitude si toutes les choses ci-dessus se dérouleront. Parce que les changements sont importants, nous devrons les tester sur Facebook et les essayer progressivement. Cela signifie que nous allons introduire un indicateur de fonctionnalité, créer une partie du code et le garder activé sur Facebook pour un petit groupe de personnes. Les versions open source 16.x conserveront l'ancien comportement, mais sur le maître, vous pourrez l'exécuter avec l'indicateur de fonctionnalité activé.

Je prévois de travailler sur le projet moi-même pour la plupart, mais j'apprécierais beaucoup plus de discussions et de contributions de @nhunzaker , @aweary , @jquense et @philipp-spiess qui ont été d'excellents collaborateurs et ont largement dirigé React DOM tout en nous travaillions sur la fibre. S'il y a un domaine qui vous intéresse particulièrement, faites-le moi savoir et nous le réglerons.

Il y a probablement des choses que j'ai ratées dans ce plan. Je suis très ouvert aux commentaires et j'espère que cet article vous sera utile.

DOM React Core Team Big Picture

Commentaire le plus utile

J'aime chacun de ces points, sauf le changement className . Cela semble carrément contradictoire avec l'objectif poursuivi par les autres points (alignement avec l'API DOM). React se lie aux propriétés DOM, pas aux attributs HTML (c'est ce même articulé dans le premier point). La propriété DOM Element est nommée className , et non class . Alors pourquoi serait-il nommé class dans React ?

Tous les 227 commentaires

J'aime cela. La réduction de la taille du bundle et la prop "classe" sont des changements qui seront les bienvenus.

Bon travail!

🙂

Avis aux auteurs de bibliothèques de formulaires ! 🤣

Génial!

className → la classe est fantastique

Qu'en est-il de tous les autres ? Cela semble bizarre de continuer à faire clipPath , htmlFor , tabIndex , etc.

L'adoption class est une avancée majeure pour rendre la bibliothèque plus conviviale pour les débutants. Toutes nos félicitations.

C'est génial. Je suis tellement curieux de savoir comment le passage à class fonctionne réellement avec les accessoires.

Il semble que ({ class }) => <div class={class} /> présente initialement un problème de mot clé réservé ?

C'est une nouvelle fantastique, merci @gaearon !

J'aime chacun de ces points, sauf le changement className . Cela semble carrément contradictoire avec l'objectif poursuivi par les autres points (alignement avec l'API DOM). React se lie aux propriétés DOM, pas aux attributs HTML (c'est ce même articulé dans le premier point). La propriété DOM Element est nommée className , et non class . Alors pourquoi serait-il nommé class dans React ?

Fantastique! Avez-vous un objectif de réduction de la taille des bundles ?

👏

Qu'en est-il de tous les autres ? Cela semble bizarre de continuer à faire clipPath, htmlFor, tabIndex, etc.

Je suis ouvert à la discussion, mais je dirais que ces changements n'en valent pas la peine (sauf for peut-être).

Je pense qu'une réécriture du système d'événements est l'aspect le plus intéressant de cela. Il existe une opportunité importante de réduire la taille du bundle et de faciliter les contributions de la communauté.

Faisons-le!

Je me demande s'il serait utile de travailler également sur la sortie de JSX 2.0 en même temps ? Les gens vont devoir réapprendre une poignée de choses de toute façon. Peut-être est-il préférable de devoir réapprendre un tas de choses à la fois plutôt que quelques choses deux fois sur une période de temps ? Juste une pensée qui m'est venue en lisant ceci.

J'aime chacun de ces points, à l'exception du changement de className. Cela semble carrément contradictoire avec l'objectif poursuivi par les autres points (alignement avec l'API DOM). React se lie aux propriétés DOM, pas aux attributs HTML (c'est ce même articulé dans le premier point).

Et pourtant, si nous passons une paire clé/valeur inconnue, elle sera traitée comme un attribut depuis React 16. Nous sommes donc déjà incohérents. De plus, mon commentaire concernait le fait que les utilisateurs se trompaient en s'attendant à ce que React définisse l'attribut value . Que l'API React utilise le nom d'attribut ou le nom de propriété dans son API est complètement orthogonal.

J'ai défendu votre point de vue sur cet argument pendant des années, mais je pense maintenant que ce sont des frictions qui n'en valent tout simplement pas la peine. Vous n'y gagnez rien. Le simple fait de laisser les gens utiliser class n'a aucun effet négatif, sauf que cela ne fonctionne pas avec la déstructuration et le coût de la migration. Tout le monde s'en plaint quand ils apprennent React. Je pense que faire ce que les gens attendent dans ce cas est plus important que d'être pédant. Et puisque nous modifions d'autres choses DOM de toute façon, regroupons cela ensemble.

Tant que React Fire est rapide comme l'éclair.... 👍

Ces changements sont tous fantastiques. Je suis très excité à propos de cela et de ses implications pour react-testing-library . En particulier, les événements liés à la racine de réaction (ou peut-être même supprimer complètement la délégation d'événements car cela n'est peut-être plus nécessaire dans les environnements modernes ?), supprimer/réécrire potentiellement des événements synthétiques, et onChange -> onInput améliorera sérieusement la mise en œuvre de react-testing-library et l'expérience d'utilisation de l'outil.

J'aimerais fournir des commentaires à ce sujet au fur et à mesure de sa mise en œuvre.

peut-être même abandonner complètement la délégation d'événements car cela n'est peut-être plus nécessaire dans les environnements modernes

Nous avons considéré cela, mais pensons que cela pourrait être une simplification excessive. La délégation d'événements nous permet d'éviter de configurer un groupe d'écouteurs pour chaque nœud sur le rendu initial. Et les échanger sur les mises à jour. Ces aspects ne doivent pas être ignorés. Il y a probablement plus d'analyses comparatives à faire là-bas.

@tannerlinsley ({ class: className }) => <div class={className} /> malheureusement, cela tuera la notation abrégée d'objet jsx 2.0 ( <div class /> ), mais tant pis ...

Ce serait super, super sympa si class pouvait enfin prendre des objets et des tableaux à côté des chaînes.

Avez-vous un objectif de réduction de la taille des bundles ?

Laisser tomber un tiers de React DOM serait bien. On verra. C'est difficile à dire tôt mais nous ferons de notre mieux.

Wow, ceci est une énumération de presque toutes les décisions de conception que je mentionne lorsque les gens me posent des questions sur les inconvénients de React.

J'adore la direction que cela prend.

Quel serait le chemin de mise à niveau pour les bibliothèques qui utilisent className et qui souhaitent prendre en charge plusieurs versions de React ?

@gaearon Peut-être que ce n'est pas grave, aujourd'hui c'est bien de dire "les accessoires sont des propriétés DOM et non des attributs HTML", maintenant ce sera "sauf className, celui-là est le nom HTML". J'aimerais aussi pouvoir copier/coller SVG sans 10 minutes de déconner avec des attributs pour correspondre à ceux de React

Qu'en est-il de htmlFor ?

Il semble que la transition className -> class devra être effectuée très soigneusement, probablement sur une longue période de temps. Cela va causer beaucoup de problèmes à l'écosystème, car pratiquement tous les composants devront être modifiés, même les plus insignifiants. C'est généralement bien si vous "possédez" le code et qu'il existe un codemod, mais lorsque vous dépendez de bibliothèques tierces, vous êtes en grande partie à la merci des responsables.

Le reste des changements semble relativement peu risqué du point de vue de l'écosystème, mais se débarrasser de className causera vraiment beaucoup de douleur. Il semble qu'il devrait être possible de diviser cela en un problème distinct et de le publier selon un calendrier différent du reste des changements 🔥.

Je suis d'accord avec @felixfbecker
Tout semble génial et améliorerait la qualité pour les développeurs et les utilisateurs, mais le changement de className.

Être capable de déconstruire toutes les propriétés mais une causerait certainement plus de confusion et serait plus difficile à expliquer aux nouveaux utilisateurs que le fait qu'ils doivent utiliser className car class est un mot-clé (qu'ils peuvent clairement voir quand l'erreur est commise, car il est coloré différemment) . Travailler autour de la classe dans la déconstruction nécessite d'introduire une nouvelle syntaxe ou une manière complètement différente de lire cette propriété spécifique qui ne fonctionnerait que jusqu'à ce que vous ayez besoin d'utiliser une propriété rest.
Cela crée de nombreux problèmes juste pour enregistrer quatre caractères.

@felixfbecker , cela pourrait-il être class / for dans JSX et className / htmlFor dans la version JS ?

<label class="foo" for="bar">..</label>

serait

React.createElement('label', {className: 'foo', htmlFor: 'bar'}, '..')

Super projet ! C'est bien d'ici ça! 👏👏👏

C'est génial, j'ai hâte de découvrir les nouveautés.

Simplifiez considérablement le système d'événements (#4751).

Désormais, react ne peut pas déléguer le gestionnaire à des éléments personnalisés, sans étendre la définition de ReactDOM. https://github.com/facebook/react/issues/9242

Cela signifie que React ne peut pas définir de gestionnaire personnalisé sur un élément personnalisé comme <x-component onMyEvent={ev => {...}} />

@gaearon
Avez-vous un plan à ce sujet?

Tous ces changements sont excellents, mais le plus grand changement méta de tous est la réduction de la taille à mon avis. React a un DX moyen, mais il est suffisamment gros pour que le téléchargement et l'analyse sur les réseaux moyens et en particulier sur les mobiles posent problème.

On pourrait tout avoir !

La réécriture de la délégation de l'événement ouvrirait-elle la porte à la correction du #1254 ; où certains événements dégradent les performances du nœud auquel ils sont attachés (ce qui pour React signifie l'ensemble de l'application).

De plus, à long terme, avez-vous envisagé d'avoir des props dataSet synthétiques ? Ne pas pouvoir taper les accessoires HTML autorisés (à cause de data-*) entraîne une tonne de bogues lors de la transmission des accessoires aux nœuds DOM. Les composants React actuellement typés doivent choisir entre des types exacts pour les accessoires et autoriser les attributs de données.

Je suis surexcité

@ryanflorence Un peu décalé mais c'est un peu triste que personne (pour autant que je sache) n'ait eu l'idée de créer un transfomer html/css/svg -> jsx afin de faciliter les migrations vers React avec autant de changements triviaux pour mapper HTML attrs aux accessoires React. Tant d'heures de travail perdues à effectuer principalement la recherche et le remplacement :(

C'est très étrange de voir ce qui suit dans le même numéro (et les commentaires):

Notre objectif est de mieux aligner React sur le fonctionnement du DOM
NomClasse → classe
Cela semble bizarre de continuer à faire clipPath, htmlFor, tabIndex, etc.

Lorsque tous ceux-ci sont des homologues directs des API DOM

Et cet argument ne passe pas le cap :

J'ai défendu votre point de vue sur cet argument pendant des années, mais je pense maintenant que ce sont des frictions qui n'en valent tout simplement pas la peine. Vous n'y gagnez rien. Le simple fait de laisser les gens utiliser la classe n'a aucun effet négatif, sauf que

React n'a toujours été qu'une très fine couche au-dessus de JS. Donc, tout le reste, à part les crochets angulaires de JSX, était JS _et_ avait une contrepartie directe dans les API DOM pour les choses directement liées à DOM : className , clipPath , htmlFor , tabIndex etc. etc. etc.

Avec la décision d'introduire class , React cesse d'être une couche mince ( class est un mot réservé dans JS) et rompt avec l'objectif déclaré d'être plus compatible avec les API DOM.

Il est particulièrement choquant de voir que vous voulez à la fois "Migrer de onChange vers onInput" car il est incohérent avec le DOM _et_ devient incohérent avec le DOM en migrant className -> class .

De plus, cela ouvre une boîte pleine de vers, car les gens exigeront (et exigent déjà) des modifications d'autres parties. Juste dans les commentaires : pourquoi utilisons-nous dataset au lieu de data-* ? Peut-être parce que data-* n'est pas JS valide (un peu comme class ) et parce que c'est cohérent avec les API DOM ? Pourquoi ne changeons-nous pas htmlFor ? Parce que for est un mot réservé et que htmlFor est dans les API DOM ? Etc. etc. etc.

Et pourtant, si nous passons une paire clé/valeur inconnue, elle sera traitée comme un attribut depuis React 16. Nous sommes donc déjà incohérents.

@gaearon qui est également la raison pour laquelle React est la seule bibliothèque à avoir obtenu de mauvais résultats au test d'interopérabilité CustomElements Everywhere : https://custom-elements-everywhere.com/
Et il y a beaucoup de problèmes demandant de le changer : https://github.com/facebook/react/issues/11347 , https://github.com/facebook/react/issues/7249 , https://github.com/facebook /réagir/problèmes/9230

Ce n'est peut-être pas un problème, mais la similitude entre React Fire et React Fiber va-t-elle prêter à confusion pour les anglophones non natifs ? J'ai souvent pensé que Newark Penn Station et New York Penn Station étant sur la même ligne de train ici à New York était une blague particulièrement cruelle pour les touristes.

Si c'est un réel souci, vous pouvez l'appeler React Flame et garder le feu 🔥 emoji.

La réécriture de la délégation de l'événement ouvrirait-elle la porte à la correction du #1254 ; où certains événements dégradent les performances du nœud auquel ils sont attachés (ce qui pour React signifie l'ensemble de l'application).

Corriger #1254 sous une forme ou une autre est certainement quelque chose que j'aimerais voir.

De plus, à long terme, avez-vous envisagé d'avoir des props dataSet synthétiques ?

Je ne veux pas m'engager dans quelque chose comme ça maintenant parce qu'il y a une plus grande surface. Une interface plus riche pour DOM ( ariaSet , dataSet , classList ) a du sens, mais on ne sait pas combien nous voulons investir dans React DOM, par rapport à une bibliothèque de niveau supérieur qui vous donne une API DOM plus riche. Étant donné que ces changements sont plus cosmétiques mais ont une grande surface, je les attendrais.

Réagissez Blazing 🔥

@ryanflorence Un peu décalé mais c'est un peu triste que personne (pour autant que je sache) n'ait eu l'idée de créer un transfomer html/css/svg -> jsx afin de faciliter les migrations vers React avec autant de changements triviaux pour mapper HTML attrs aux accessoires React. Tant d'heures de travail perdues à effectuer principalement la recherche et le remplacement :(

@jxub
https://transform.now.sh/html-to-jsx/

Tellement excités par les nouveaux changements, vous, les humains de Facebook, entrez dans l'histoire avec cette migration. 50 000 composants seront migrés vers React Fire ?
Vos suites de tests doivent être si serrées <3

la similitude entre React Fire et React Fiber va-t-elle prêter à confusion pour les anglophones non natifs ?

peut-être aussi pour les malentendants (ou ceux qui ont d'autres conditions affectant la discrimination des mots)

Merci pour le partage @gaearon , c'est incroyable !

J'aimerais voir une version JSX 2.0 résoudre le problème d'espace blanc et de nouvelles lignes qui se produit lorsque nous compilons notre code avec Babel et Typescript.

Il y a différents problèmes ouverts et j'ai essayé de contribuer mais j'ai été réprimandé car l'équipe React doit tout revoir autour de JSX.

Ce problème concerne de toute façon le dom, car la façon dont nous traduisons jsx en js ne permet pas ce que dit le w3c.

C'est le problème https://github.com/facebook/jsx/issues/19

Mon commentaire est à la toute fin.

Je pense que className est correct. Laissez-le être ce qu'il est. N'ajoutez pas l'insulte à l'injure.

Quelqu'un peut-il clarifier comment cela affecte les gestionnaires existants ?

Arrêter de refléter les valeurs d'entrée dans l'attribut de valeur

React aura-t-il toujours des entrées contrôlées avec des mises à jour précises event.target.value dans les gestionnaires, ou cela n'affecte-t-il que la lecture des valeurs des références et des nœuds DOM ?

@nickmcurdy il affecte ce que vous voyez dans le navigateur devtools

@tomdale Réagissez Ember 🔥

Agréable! J'attends de voir la liste complète des changements dans React 17.
Je pense que ce sera une nouvelle ère de ReactJS. 🔥⚛️

@tomdale Hmm : fil, fibre, tissu ; peut-être qu'un autre terme lié aux vêtements pourrait être utilisé ? 😆

Et pourtant, si nous passons une paire clé/valeur inconnue, elle sera traitée comme un attribut depuis React 16. Nous sommes donc déjà incohérents.

@gaearon qui est également la raison pour laquelle React est la seule bibliothèque à avoir obtenu de mauvais résultats au test d'interopérabilité CustomElements Everywhere : https://custom-elements-everywhere.com/

Non, ce n'est pas la raison (les éléments personnalisés et normaux sont des chemins de code complètement séparés). La raison en est que nous avions déjà l'ancien comportement et que nous ne voulions pas casser la rétrocompatibilité à moins que le nouveau comportement ne soit solide. Je pense qu'il serait logique de s'attaquer à une meilleure interopérabilité des éléments personnalisés dans le cadre de ce parapluie.

la similitude entre React Fire et React Fiber va-t-elle prêter à confusion pour les anglophones non natifs ?

Les deux sont des noms de code internes et n'ont pas vraiment de signification une fois les projets terminés. React Fire n'est qu'un effort pour améliorer React DOM - et au moment où il sera prêt pour la production, ce ne sera plus que React DOM.

React aura-t-il toujours des entrées contrôlées avec des mises à jour précises de event.target.value dans les gestionnaires, ou cela n'affecte-t-il que la lecture des valeurs des refs et des nœuds DOM ?

Oui, car event.target.value est une propriété . Nous parlons d'arrêter la mise à jour des attributs . Ce qu'aucune autre bibliothèque populaire ne fait (AFAIK) et qui cause d'innombrables problèmes. Cela ne devrait pas affecter votre code à moins que vous ne vous appuyiez sur des sélecteurs CSS sur la valeur (ce qui est probablement mauvais de toute façon).

Agréable! J'attends de voir la liste complète des changements dans React 17.

Notez que nous ne nous engageons pas à ce que ce soit prêt à 17 heures. Il pourrait être 18. Ou 19. 😅

C'est agréable de voir un développement constant sur une si bonne bibliothèque comme React. 🎉 class rendra la convivialité bien meilleure, ça vaut le coup imo

@gaearon

les éléments personnalisés et normaux sont des chemins de code complètement séparés

Cela en soi semble être quelque chose à réparer aussi. Y a-t-il une raison de ne pas traiter tous les éléments de la même manière ? C'est l'intention des spécifications HTML et DOM.

@justinfagnani Comme indiqué précédemment, la raison pour laquelle nous ne l'avons pas fait à l'époque était qu'il n'y avait pas de convention sur la manière de déterminer s'il fallait définir une propriété ou un attribut - et il y avait un risque qu'en utilisant une vérification, nous risquions de le faire impossible pour la plateforme web d'ajouter de nouvelles propriétés au prototype. Je pense qu'il existe déjà une sorte de consensus dans les RFC et les PR sur lesquels @robdodson a travaillé, et nous pouvons probablement le reprendre à partir de là.

👍 🔥 🔥 🔥

React Fire devrait également nous permettre d'appliquer certaines des optimisations de performances intelligentes d'Inferno, mais qui n'ont pas pu être appliquées en raison de modifications radicales. Des moments passionnants :)

LGTM

Lié à la proposition de renommer className -> class : j'aimerais une propriété classes qui prend un tableau de chaînes. Cela m'éviterait de nombreuses manipulations de chaînes (ou l'utilisation de classnames ) dans mes composants.

Je pense que le seul inconvénient d'un prop classes serait que les tableaux contenant les mêmes chaînes dans le même ordre provoqueraient un nouveau rendu en composant pur, alors qu'une chaîne des mêmes classes CSS ne le ferait pas. Honnêtement, cela semble être un problème mineur. Je pense que la plupart des développeurs de React connaissent déjà les compromis entre les tableaux et les objets dans les accessoires.

@gaearon a des plans pour la rétrocompatibilité ? Suivez peut-être le même chemin que React Fiber, en ajoutant des avertissements sur les modifications et en donnant du temps pour la mise à jour des grandes bases de code sans perdre de nouvelles mises à jour.

Concernant class et className .

Je sais que nous n'obtiendrons pas un large accord à ce sujet, quelle que soit la voie que nous emprunterons. Les gens ont des opinions très tranchées sur celui-ci. Je veux partager ce que j'en pense, dans l'espoir qu'il sera utile.

L'API de composant devrait sembler idiomatique

Il existe un argument commun selon lequel React "correspond à JavaScript" et donc className est préféré. Je pense que cette affirmation est subtilement mal comprise, j'aimerais donc m'y attarder un peu.

Dans React, avant tout, nous veillons à ce que l'utilisation d'un composant React ressemble à du JavaScript idiomatique . Cela signifie que si j'utilise un composant hypothétique <Table> , je m'attends à ce que ses accessoires soient camelCase :

<Table
  rowHeight={10}
  headerBorderInset={5}
  renderRow={this.renderRow}
/>

Je ne m'attends pas à voir des noms d'accessoires comme row_height ou row-height dans l'API publique d'un composant . Les accessoires du composant sont un objet (un peu comme un "sac d'options"), et nous nous attendons généralement à ce que ces options soient camelCase . Ce n'est peut-être pas toujours idiomatique dans DOM, mais le DOM n'est pas très cohérent dans de nombreux endroits. React s'aligne sur l'écosystème JavaScript qui utilise massivement camelCase .

Mais qu'en est-il des DOM ? C'est là que ça devient épineux.

Les propriétés DOM ne sont pas simplement des "attributs dans JS"

Dans DOM, nous avons des attributs et des propriétés. Les attributs sont les choses que vous voyez habituellement en HTML. Les propriétés sont les choses que vous définissez habituellement à partir de JS. Mais surtout, les API DOM existent à la fois pour définir les propriétés et pour définir les attributs - et elles ne définissent même pas toujours la même chose.

node.value = 10; // setting a property
node.setAttribute('value', '10'); // setting an attribute

Dans de nombreux cas, cela n'a pas d'importance. Dans certains cas, c'est le cas. Mais peut-être pas de la manière dont on pourrait penser en utilisant React (qui a une abstraction sur les deux).

React ne consiste pas seulement à définir des propriétés

Une idée fausse courante est que puisque React utilise actuellement la convention camelCase pour la plupart des accessoires DOM, cela signifie que React définit les propriétés DOM. C'est faux.

En fait, React utilise actuellement des attributs pour presque tous les accessoires qu'il prend en charge. Dans certains cas, comme value , cela cause des problèmes (que nous voulons inverser, comme je l'ai dit). Dans d'autres cas, c'est en fait très bien, car nous n'avons pas besoin d'inclure une liste des propriétés prises en charge dans le bundle React. L'utilisation d'attributs sous le capot est ce qui a permis une réduction majeure de la taille dans React 16.

Ce que je veux dire ici, c'est que si React utilise des propriétés ou des attributs en interne est un détail d'implémentation - et n'a rien à voir avec le fait que l'élément React DOM _API_ doive utiliser des noms de propriété, des noms d'attribut ou même d'autres noms qui ont du sens.

Pourtant, utilisons simplement les noms de propriété ?

D'accord, les propriétés et les attributs sont un détail d'implémentation. Mais pourquoi ne pas simplement normaliser l'utilisation des noms de propriétés DOM puisque ceux-ci ont été spécifiquement créés "pour JavaScript" ? N'est-ce pas ainsi que l'API React est conçue aujourd'hui ?

Eh bien, pas tout à fait. Une seule des props énumérées ci-dessous correspond à une véritable propriété d'objet DOM :

<div
  tabIndex={1}
  data-id="123"
  aria-live="polite"
  nopin="nopin"
  itemType="http://schema.org/Movie"
  onClick={function() { alert('hi') }}
/>

Ironiquement, le seul accessoire ci-dessus qui a une propriété DOM réelle avec le même nom correspondant ( tabIndex si vous n'étiez pas sûr) est en fait défini par React en tant qu'attribut !

Donc, à ce stade, vous voyez probablement que ce n'est ni clair ni cohérent. Dans certains cas, les propriétés n'existent pas (comme pour les attributs personnalisés non standard), dans certains cas, React pourrait fournir une API plus riche ( data- vs dataSet ) mais ce n'est pas le cas actuellement.

Dans certains cas, React choisit intentionnellement de dévier ( onClick dans React vs onclick propriété DOM) car cela a plus de sens pour les composants React personnalisés. En effet, les composants React exposent souvent des gestionnaires d'événements plus complexes comme onItemClick . Ce serait très incohérent si vous écriviez <Button onclick> mais <Table onItemClick> . Et <Table onitemclick> n'est pas camelCase, ce que nous voulions éviter dans une API de composant.

Ci-dessus, j'ai expliqué que React n'est déjà pas cohérent sur "toujours utiliser le nom de la propriété DOM", que React n'utilise même pas réellement les propriétés en interne (de sorte que cette règle empirique ne décrit pas non plus la mécanique réelle), et que dans de nombreux cas, les propriétés DOM n'existent tout simplement pas, nous devons donc nous en tenir à autoriser le nom de l'attribut.

Si ce ne sont pas des noms de propriété, soyons cohérents et utilisons des noms d'attribut ?

Alors pourquoi ne pas utiliser uniquement les noms d'attributs ? Cela pourrait être plausible. Mais maintenant nous tombons sur la toute première considération que nous avons soulevée. L'utilisation d'un composant React devrait ressembler à du JavaScript idiomatique . Mais souvent, les composants transmettent au moins quelques accessoires à l'élément DOM sous-jacent.

<Button
  borderColor='red'
  tabIndex={1}
 />

 // renders...

 <button
   tabIndex={1}
/>

Il serait gênant pour un Button personnalisé d'accepter des props avec des majuscules incohérentes :

<Button
  borderColor='red'
  tabindex={1}
 />

Cela oblige le consommateur à toujours se souvenir si un certain accessoire est un accessoire DOM réel, ou juste une partie du contrat de composant. Même cette distinction est floue - un composant peut choisir de passer d'abord un certain accessoire, mais ensuite de commencer à l'utiliser pour une logique supplémentaire. Où placez-vous la frontière entre les "accessoires DOM" et les "autres accessoires" ?

Je pense que c'est la principale raison pour laquelle il est souhaitable que les props comme tabIndex , cellSpacing et la plupart des autres props liés au DOM suivent la convention camelCase. C'est parce qu'ils se retrouvent souvent dans des API de composants.

Nous voulons qu'il soit facile pour les composants personnalisés comme Button de les envelopper et de les transmettre sans les "traduire" en nom d'attribut au point où ils circulent dans le DOM, et sans introduire d'accessoires autres que camelCase dans un API de composant personnalisé.

Cela explique également pourquoi les accessoires comme data-* , aria-* et les attributs personnalisés sont des exceptions raisonnables (même si nous pourrions créer des API plus riches pour eux). Ils sont rarement transmis aux composants personnalisés. En règle générale, ils sont trop couplés au DOM pour être utiles dans les composants personnalisés - et à la place, ils deviennent un détail d'implémentation de quelque chose comme un <Modal> ou un <Button> avec une API camelCase plus riche.

Les propriétés React ne correspondent déjà pas aux propriétés DOM

Si la convention "nom de propriété DOM" n'a pas fonctionné, nous avons besoin d'autre chose. Qu'est-ce que c'est? Pourrait-il s'agir de "version camelCase du nom d'attribut" ? Il semble que cela vérifie presque toujours déjà.

Si cela semble trop radical, considérez que nous le faisons déjà. Nous soutenons quelque chose appelé srcSet . Mais le nom de la propriété DOM est srcset . Nous avons autoCapitalize mais la propriété DOM s'appelle autocapitalize . Nous avons autoFocus mais la propriété DOM est autofocus .

Nous nous éloignons déjà des noms de propriété DOM lorsqu'ils ne correspondent pas à la convention JavaScript camelCase. Ce qui nous amène à class .

Enfin : className contre class

Une partie de la justification originale pour en faire className était parce que React définissait les propriétés DOM, et className est le nom de la propriété DOM.

Cependant, comme je l'ai expliqué plus haut, React n'utilise plus de propriétés sauf trois ou quatre cas particuliers. Plus important encore, React n'utilise même pas systématiquement les noms de propriété DOM - il utilise plutôt des noms qui sembleraient naturels lorsqu'ils sont utilisés à partir de JavaScript, quelle que soit l'incohérence de dénomination interne dans les noms d'attributs et de propriétés DOM. Et c'est parce que React se soucie le plus de garder les noms d'accessoires pour les composants personnalisés comme "JavaScripty". En ce sens, tabindex n'est pas "JavaScripty" - mais class et className sont.

Un autre argument contre class au début était qu'un code comme celui-ci n'était pas valide ES3 (pertinent pour IE8):

// Not valid in ES3
// Valid in ES5
var props = { class: 'foo' };

Mais la plupart n'écrivent plus ES3. Soit vous utilisez une chaîne d'outils comme Babel, soit vous ciblez probablement IE9 + - React ne prend même pas en charge IE8 maintenant.

Donc, le seul inconvénient qui reste avec class est que vous ne pouvez pas écrire ceci :

// Not valid at all :-(
const class = props.class;
const { class } = props;

Mais je pense qu'avec le temps, cet argument n'est plus assez fort en lui-même. React ne vous oblige pas à utiliser la déstructuration ou à utiliser ce nom de variable spécifique, et à écrire quelque chose comme

// Valid
const {class: cls} = foo;
const cls = props.class;

n'est pas beaucoup plus d'effort.

Généralement, les gens transmettent class beaucoup plus souvent qu'ils ne le lisent, car de nombreux composants contiennent plus d'un <div> interne ou d'autres éléments hôtes. Donc, vous finissez par écrire <div className> beaucoup plus souvent que de vouloir déstructurer class . Et ainsi, le passage à class économiserait plus de frappe au clavier qu'il n'en introduirait.

Il y a un autre point important ici.

Passer class à plusieurs niveaux n'est pas un bon schéma en soi. C'est nécessaire pour les bibliothèques, mais dans le code d'application, cela conduit souvent à des composants fragiles. Ceux dont les styles cassent tout le temps parce qu'il y a une centaine de sites d'appels différents ajoutant chacun une classe différente, provoquant des bogues en cascade. Il n'est donc pas clair à quel point il est utile d'encourager la déstructuration class en premier lieu. Je pense que c'est bien que vous ayez besoin d'écrire une ligne de code supplémentaire pour le lire à partir des accessoires (ou vous pouvez simplement utiliser props.class et ne pas y penser).

Si vous écrivez un composant très proche du DOM (et qu'il est donc logique qu'il prenne class comme accessoire), vous souhaiterez probablement également transférer d'autres accessoires. Vous pouvez donc utiliser la syntaxe rest dans la déstructuration :

// Valid in ES2018

function Button({ color, ...rest }) {
  const buttonClass = rest.class +  ' Button-' + color;
  return <button {...rest} class={buttonClass} />
}

Et si vous n'aviez pas besoin de le modifier, vous auriez pu simplement transférer {...rest} sans même en lire class . Ainsi, la limitation de déstructuration pourrait aider à encourager une meilleure conception des composants.

Pourquoi pas les deux?

why not both

Enfin, ne pouvons-nous pas simplement prendre en charge à la fois class et className ? D'une certaine manière, nous le faisons déjà, mais React vous crie dessus avec un avertissement. Il y a une raison pour cela.

Si nous prenons en charge les deux sans avertissement, la communauté se divisera sur celui à utiliser. Chaque composant sur npm qui accepte un accessoire de classe devra se souvenir de transmettre les deux. Si même un composant au milieu ne joue pas le jeu et n'implémente qu'un seul accessoire, la classe se perd - ou vous risquez de vous retrouver avec class et className en bas "en désaccord" avec chacun autre, sans aucun moyen pour React de résoudre ce conflit. Nous pensons donc que ce serait pire que le statu quo et nous voulons éviter cela.

Sommaire

Si React était open source aujourd'hui, il semble que les avantages d'autoriser class (plus proche conceptuellement de ce que la plupart des gens attendent, moins de frappe pour l'accessoire le plus couramment utilisé) l'emportent sur les inconvénients (un peu plus de frappe pour l'intercepter - dans auquel cas vous voudrez probablement juste l'opérateur de propagation de toute façon).

Ce que nous avions l'habitude de considérer comme des inconvénients (incohérents avec les propriétés DOM) est sans objet car nous ne définissons plus les propriétés DOM, ni même ne nous efforçons d'être cohérents avec elles. Au lieu de cela, nous visons à avoir une API basée sur les attributs mais camelCase du côté consommateur des composants React – ce à quoi nous sommes déjà presque cohérents. Et class="Button" est nettement plus pratique que className="Button" . En fait, si l'API DOM était conçue aujourd'hui, elle vous permettrait probablement de définir la propriété .class précisément parce que la restriction d'utilisation class dans une tâche comme celle-ci a été levée dans ES5 - il y a près de dix ans.

Le seul gros inconvénient restant est le coût de la migration. Nous évaluerons cela avec soin. Mais si nous faisons quand même un tas de changements, nous pourrons peut-être faire celui-ci aussi et le réparer pour de bon. Nous ne réfléchissons pas à cela à la légère et nous prenons toutes vos préoccupations en considération.

Remarque : cela peut être utile pour d'autres noms d'accessoires React qui ne correspondent pas aux noms d'attribut camelCased.

@renatoagds

avez-vous des projets de rétrocompatibilité ? Suivez peut-être le même chemin que React Fiber, en ajoutant des avertissements sur les modifications et en donnant du temps pour la mise à jour des grandes bases de code.

Comme je l'ai noté :

Et nous avons plus de 50 000 composants sur Facebook pour rester honnêtes sur notre stratégie de migration. Nous ne pouvons pas nous permettre de réécrire le code du produit, à l'exception de quelques correctifs ciblés ou de codemods automatisés.

Nous allons donc certainement essayer de rendre la stratégie de migration aussi fluide que possible, comme nous le faisons toujours. Si ce n'est pas facile, nous ne pourrons pas faire le changement nous-mêmes.

re: className -> classe, je suis d'accord avec la décision, je peux certainement voir l'exception au changement de classe pour les nouveaux utilisateurs, et un avantage secondaire de lignes de code plus courtes. Cependant, ils auraient encore besoin de se renseigner sur les autres noms camelCase.

Donc, le seul inconvénient qui reste avec la classe est que vous ne pouvez pas écrire ceci :

const { class } = props;

Mais je pense qu'avec le temps, cet argument n'est plus assez fort en lui-même. React ne vous oblige pas à utiliser > la déstructuration et l'écriture

const class = props.class;

n'est pas beaucoup plus d'effort.

Deux (éventuellement petites) choses :

  1. const class = props.class JavaScript n'est-il pas invalide ? Je ne pensais pas que c'était le cas, et dans un test rapide, Chrome ne l'aime pas. En outre, cet article suggère qu'il n'est pas valide.

  2. Je pouvais voir ce changement être un (encore une fois, potentiellement petit) domaine de frustration pour les gens qui écrivent des composants comme celui-ci : nvm (voir la mise à jour ci-dessous)

const { oneProp, twoProp, className, ...rest }  = this.props;

// do stuff with oneProp, twoProp, className

return (
  <div
    someProp={prop}
    anotherProp={anotherProp}
    className={someClassName}
    {...rest}/>
);

Après ce changement, cela devrait être quelque chose comme...

const { oneProp, twoProp, ...rest }  = this.props;

// do stuff with oneProp, twoProp, this.props.className

return (
  <div
    someProp={prop}
    anotherProp={anotherProp}
    {...rest}
    class={someClassName}/>
);

Il n'est pas impossible de contourner ce changement, mais c'est un peu plus à garder à l'esprit lors de l'écriture et de la lecture de composants dans ce style.

Mise à jour :

Ça ne fait rien,

const { class: className } = this.props;

fait l'affaire.

Le seul gros inconvénient restant est le coût de la migration. Nous évaluerons cela avec soin. Mais si nous faisons quand même un tas de changements, nous pourrons peut-être faire celui-ci aussi et le réparer pour de bon. Nous ne réfléchissons pas à cela à la légère et nous prenons toutes vos préoccupations en considération.

Heureusement, cela est facilement atténué si l'on utilise une approche CSS-in-JS, comme Aesthetic. Merci pour l'incroyable écriture!

Astuce aléatoire concernant les noms d'attributs, j'ai trouvé l'excellent projet, svg2jsx est idéal pour convertir de gros SVG à utiliser dans React !

@jamesPlease Désolé, mon esprit s'est vidé - vous avez raison. Édité.

@jamesPlease vous avez raison. Cela revient aussi fréquemment avec JSON, pour la valeur par défaut, tellement ennuyeux !

const { default: defaultVal } = property

Pendant que vous modifiez le système d'événements, ce serait vraiment bien de voir quelque chose de similaire à la fonction linkEvent d'Inferno afin que nous puissions gérer les événements en utilisant des accessoires dans les composants fonctionnels sans avoir à créer une fonction anonyme à chaque rendu.

className -> class sera un énorme changement pour l'écosystème, de nombreux composants non maintenus deviendront incompatibles et vous ne pourrez rien faire si vous ne pouvez pas les corriger. Peut-être avez-vous un wrapper comme StrictMode qui désactive ce changement pour les composants plus profonds dans l'arborescence afin de fournir un chemin de migration progressif ?

Je pouvais voir ce changement être un (encore une fois, potentiellement petit) domaine de frustration pour les gens qui écrivent des composants comme celui-ci :

const { oneProp, twoProp, className, ...rest }  = this.props;

// do stuff with oneProp, twoProp, className

return (
 <div className={someClassName} {...rest}/>
);

Ne le déstructurez pas.

const { oneProp, twoProp, ...rest }  = this.props;

return (
  <div
    {...rest}
    class={'something ' + rest.class}
  />
);

@gaearon

si React utilise des propriétés ou des attributs en interne est un détail d'implémentation

Cela semble être un problème aussi, honnêtement. Les éléments DOM peuvent se comporter et se comportent différemment dans certains cas selon que vous définissez des attributs ou des propriétés. React ne peut pas connaître toutes les différences, mais les utilisateurs d'éléments peuvent connaître les éléments qu'ils utilisent. Un contrôle explicite sur les propriétés, les attributs et les événements permettrait aux auteurs de sortir de cette situation.

@justinfagnani Si vous souhaitez que nous modifiions des choses spécifiques, cela vous dérangerait-il de déposer un problème séparé avec une API que vous suggérez ? Cela semble un peu hors de portée de ce problème.

@sompylasar

className -> class sera un énorme changement pour l'écosystème, de nombreux composants non maintenus deviendront incompatibles et vous ne pourrez rien faire si vous ne pouvez pas les corriger. Peut-être avez-vous un wrapper comme StrictMode qui désactive ce changement pour les composants plus profonds dans l'arborescence afin de fournir un chemin de migration progressif ?

Je suis d'accord - et nous pesons toujours le pour et le contre. Rien n'est finalisé.

Mais en pratique, le problème des composants non maintenus n'est pas nouveau - il apparaît à chaque version majeure de React parce que quelque chose change dans les majeures par définition (nous ne pouvons pas avancer autrement, et nous n'avons pas le luxe de conserver tout le code hérité dans le bundle pour toujours contrairement aux environnements de serveur, par exemple). Le même problème est survenu lorsque PropTypes a été déplacé dans un package séparé, et se reproduira avec le changement de nom du cycle de vie UNSAFE_ . Les paquets non maintenus sont dupliqués ou corrigés. Nous réalisons que c'est un gros gouffre de temps, et c'est pourquoi nous évitons de faire plus d'un gros majeur par an. Pour les personnes qui n'ont pas les moyens d'aider, attendre généralement quelques mois avant de passer à une nouvelle majeure est la meilleure stratégie, car les premiers utilisateurs ouvrent la voie et font revivre les packages abandonnés. Ensuite, nous avançons tous ensemble.

Encore une fois - je comprends très bien votre hésitation, mais ce n'est pas fondamentalement différent des autres changements de rupture qui se sont produits dans le passé ou qui pourraient se produire dans le futur. Comme toujours, nous mettrons beaucoup d'efforts et mettrons l'accent sur les scripts automatisés que vous pouvez exécuter pour convertir la majeure partie de votre base de code, et que vous pouvez également exécuter sur d'autres packages (et leur envoyer des PR - ou les forker dans leur dernier état ).

Quelle que soit votre décision, un autre argument contre class est la possibilité de recherche. Combien de faux positifs vous donneront une recherche par class lorsque vous vouliez trouver des composants qui utilisent des classes CSS dans du code ES6 qui utilise des composants de classe JS ? Oui, vous pouvez rechercher class={ , mais qu'en est-il de la déstructuration des accessoires dans JSX qui sont créés en tant qu'objet dans JS ? (Je suis contre l'utilisation intensive de la déstructuration des accessoires, mais ils sont toujours utilisés) Bien sûr, nous avons besoin de meilleurs outils de recherche contextuels basés sur AST dans les éditeurs de code, mais pour l'instant nous n'avons que du texte et des expressions régulières. Bien sûr, les systèmes de type peuvent aider à suivre le passage d'objets, mais une grande population ne les a pas adoptés.

Quelque chose à propos de l'utilisation d'un mot réservé ne me convient tout simplement pas, même si cela ne pose aucun problème maintenant ; peut-on dire avec certitude que rest.class (par exemple) ne sera pas significatif pour la langue dans x ans ?

@GeordieP Si cela fonctionne aujourd'hui, il ne peut pas casser demain. C'est le principe de base de l'évolution de JavaScript et la raison de beaucoup de ses idiosyncrasies.

@gaearon Assez juste, alors. Si c'est une victoire assez importante, je dis allez-y.

@sompylasar Je recherche généralement className= ou className: , il semble que les deux fonctionnent également avec class .

Veuillez vous débarrasser de className , et pour l'amour de Dieu, htmlFor . Je ne suis pas un développeur DOM, généralement il y a quelque chose de très très mal si je dois accéder aux méthodes DOM natives. Le plus grand défi que j'ai à intégrer les gens à React est l'abstraction que JSX fait sur le DOM et ses étranges attributs HTML de remplacement. Tout est transpilé, aucune raison de s'inquiéter des mots réservés à ce stade. OMI.

Je ne suis pas sûr que cela ajoute quoi que ce soit à la discussion existante, mais il semble qu'il devrait y avoir une meilleure raison de changer className .

Est-ce que sauver les apprenants débutants React d'un nom légèrement peu intuitif mérite que tout le monde doive mettre à jour ses projets et son comportement ?

En tant que personne qui utilise généreusement la déstructuration, devoir se souvenir de cette nouvelle exception à la règle est probablement un hoquet mental plus important que la rare occasion où j'écris class au lieu de className .

De plus, les débutants ne seraient-ils pas encore confus par la grande quantité de matériel (comme les blogs/dépôts/etc) qui utilise actuellement className ?

Enfin, comme l'a dit @sompylasar , cela nuit à la capacité de recherche dans ma base de code.

C'est peut-être un argument de type onglets vs espaces, mais je ne comprends pas totalement pourquoi ce changement est nécessaire. Cela semble être un coût important pour un gain minime, à moins que cela ne fasse partie d'un changement plus important dans la façon dont vous souhaitez modéliser l'API au fil du temps. Cela dit, j'utiliserai à coup sûr tout ce que vous déciderez 😅.

Un peu décalé mais c'est un peu triste que personne (pour autant que je sache) n'ait eu l'idée de créer un transfomer html/css/svg -> jsx afin de faciliter les migrations vers React avec autant de changements triviaux pour mapper les attrs HTML à Réagissez les accessoires.

@jxub - J'ai construit un convertisseur HTML vers JSX dans le cadre d'un hackathon en 2014 : https://magic.reactjs.net/htmltojsx.htm. Je ne sais pas s'il gère bien SVG, cependant. Le projet de hackathon consistait à créer un script qui "ajaxifierait" un site HTML simple en utilisant React (https://github.com/reactjs/react-magic) et une partie de cela m'obligeait à créer un moyen de créer un composant React à partir d'un morceau de HTML, j'ai donc publié la partie HTML vers JSX en tant que page autonome distincte.

Nous nous soucions toujours de la prise en charge d'IE11, mais il est possible que nous n'essayions pas de lisser certaines des différences de navigateur existantes, ce qui est la position adoptée par de nombreuses bibliothèques d'interface utilisateur modernes.

@gaearon - Quels sont quelques exemples de bibliothèques d'interface utilisateur modernes qui ne lissent pas les différences de navigateur ? Pour moi, c'est l'une des principales raisons d'utiliser une bibliothèque.

Théorie du complot : toute cette nouvelle de className / class est une chose brillante et controversée à laquelle tout le monde prêtera immédiatement attention et débattra. Il s'agit soit d'attirer l'attention sur le projet de refonte dans son ensemble, soit de détourner l'attention de quelque chose de plus grand qui se passe dans l'ombre, soit de donner une chose qui peut être rétractée plus tard tandis que le reste sera accepté, comme dans l'anecdote suivante :

Le grand artiste théâtral Tyshler, créant des croquis de décors, dessinant dans le coin un petit chien vert. Et quand l'un des membres du comité d'admission a demandé: "J'aime tout, mais où est ce chien?", L'artiste avec un soupir de regret l'a plâtrée.

Les véritables raisons de ce changement ne sont pas claires, mais elles ont déjà fait monter en flèche la popularité de ce nouveau projet de mise à niveau et le buzz de la communauté autour de React.

Ce serait bien si la prise en charge des Passive Event Listeners était dans le cadre de React Fire, qui est une fonctionnalité importante sur mobile.

6436

Merci pour tout votre travail acharné sur ce point, mais veuillez reconsidérer className -> class .

Nous étions tous des débutants React et className ne nous ont pas empêchés d'apprendre et d'aimer React.

Je me souviens quand j'utilise vue avec jsx, ils avaient déjà class pas className , je ne suis pas d'accord si className sera changé en class , car React est pionnier dans Virtual DOM , et représentent le DOM lui-même.

Joindre des événements à la racine de React plutôt qu'au document

@gaearon Cela signifie-t-il que dans un environnement de test, je n'aurai pas à ajouter d'éléments au document pour pouvoir envoyer de vrais événements de navigateur et que les gestionnaires qui leur sont associés soient appelés? Devoir faire cela est très contre-intuitif et je suis sûr que de nombreux développeurs peu familiers avec les composants internes de React sont confus, perdent beaucoup de temps à écrire des tests et s'engagent dans la simulation d'événements et de mauvaises pratiques de test.

Ce qui m'amène à une autre note, pouvons-nous faire quelque chose à propos react-dom/test-utils ? Je suis particulièrement intéressé par la suppression possible de Simulate compte tenu de tous les problèmes qui y sont associés que nous connaissons tous, et bien sûr faire les changements nécessaires dans react-dom lui-même afin qu'il ne soit vraiment pas nécessaire plus. Cela pourrait-il être dans la portée?

/cc @kentcdodds

J'aime la direction et la vue d'ensemble que prend React Fire. Jusqu'à présent, cela ressemble à de grands changements vers lesquels travailler.

J'adore la plupart des changements annoncés, mais je suis sceptique quant au changement className .

React ne vous oblige pas à utiliser la déstructuration ou à utiliser ce nom de variable spécifique, et écrire quelque chose comme (... extrait de code...) ne demande pas beaucoup plus d'efforts.

Bien que l'écriture ne demande pas beaucoup d'efforts, d'après mon expérience actuelle, je m'attendrais à ce qu'il soit _way_ plus difficile à expliquer aux autres développeurs (en particulier aux développeurs d'autres langages). D'un autre côté, au cours de toutes les années où nous avons utilisé React dans notre entreprise, je suppose que seuls un ou deux développeurs ont été confus par className et l'ont simplement accepté comme API Reacts pour définir les noms de classe en quelques minutes.

(À mon avis personnel, alors que j'adore la destruction, la syntaxe de renommage semble parfois étrange en soi pour les débutants, car elle est différente du renommage dans les importations qui semble assez similaire et peut être combiné avec des choses comme les valeurs par défaut. On _pourrait_ simplement ne pas utiliser la destruction alors , mais ce serait une _grosse_ exception à tous les autres codes que nous écrivons actuellement dans notre entreprise. L'expérience des autres peut différer bien sûr, mais c'est mon point de vue sur le problème 🙃.)

génial

Également sceptique quant au changement className . C'est l'un des changements les plus mineurs dans l'ordre des choses, mais il attire une grande partie de la discussion des commentaires ici.

Cela vaut-il vraiment la peine de dépenser autant de capital politique pour un changement, alors qu'il y a tant d'autres bonnes choses qui sont annoncées ?

D'où je me tiens, si vous prenez une décision où une partie de la justification est "et écrire quelque chose comme... ... n'est pas _ça_ beaucoup plus d'efforts.", cette décision doit avoir un avantage _massif_, et le changement className -> class n'est tout simplement pas en comparaison avec tout ce qui a été annoncé.

ce sera une avancée majeure sur 🔥 React Fire

À propos class v/s className , je pense que nous devrions nous rappeler que JSX ≠ React.

Étant donné que JSX est un _DSL_ conçu pour ressembler à HTML, il est préférable de le garder aussi proche que possible de HTML. Certes, il s'appelle className dans l'API DOM, mais la plupart utilisent probablement JSX parce qu'ils ne veulent pas traiter directement avec l'API DOM.

S'il est plus logique que l'API de React corresponde étroitement à l'API DOM, alors j'espère que c'est ok/possible de faire le mappage dans la transpilation :
<img src="avatar.png" class="profile" />React.createElement("img", { src: "avatar.png", className: "profile" }) .

Il serait très utile de faire de la syntaxe JSX un sur-ensemble propre de HTML.

Pour ajouter à ce que @ mhenr18 a dit.

Etat actuel des choses :

  • La réaction est incohérente
  • L'API est camelCase

Etat des lieux proposé :

  • La réaction est incohérente
  • L'API est camelCase
  • className -> class

Avantages perçus:

Si React était open source aujourd'hui, il semble que les avantages d'autoriser la classe (plus proche conceptuellement de ce que la plupart des gens attendent, moins de frappe pour l'accessoire le plus couramment utilisé) l'emportent sur les inconvénients (un peu plus de frappe pour l'intercepter - dans quels cas vous Je veux probablement juste l'opérateur de propagation de toute façon).

Inconvénients réels :

  • tout l'écosystème qui dépend de className cesse de fonctionner (énorme effort de mise à niveau)
  • l'ensemble du vaste corpus de livres, de tutoriels, d'exemples, de code, de messages, d'articles devient légèrement invalide
  • le seul JS valide restant est un typage supplémentaire : const {class: cls} = props . Tous les autres cas d'utilisation possibles dans JS simple deviennent invalides
  • L'API React reste incohérente et casse d'autres hypothèses (pourquoi htmlFor pas for etc.)

Si j'étais chef de produit, ma réaction immédiate au changement serait : quoi ?

@gaearon Vous avez peut-être déjà pensé à cela, veuillez étiqueter les relations publiques avec "React Fire" ou un mot-clé similaire.

Les problèmes sont généralement étiquetés correctement, les PR n'en ont parfois pas. Cela aide les contributeurs potentiels.
Cela vient de mon expérience lorsque j'essayais de lire l'historique de git à la recherche de commits liés à React Fiber et React Reconciler pendant tout le développement de Fiber. Cela aide ceux d'entre nous qui essaient de comprendre ce qui se passe et de voir si nous pouvons contribuer d'une manière ou d'une autre.

Je pense aussi que renommer className en class causera un gros effort de migration et des problèmes pour les nouveaux développeurs.
L'attribut className est tellement visible et fortement utilisé qu'il va littéralement casser toutes les bibliothèques qui dépendent de react.
Et cela ne suffit pas, la plupart des tutoriels seront cassés. Un nouveau copier-coller d'appareil à partir d'un article se demandera "pourquoi cela ne fonctionne-t-il pas, il dit que className n'est pas un accessoire valide".
Donc, le senior doit aider et nous n'avons rien gagné, car nous devons encore expliquer pourquoi cela ne fonctionne pas comme vous le souhaiteriez.
Et pour de vrai, expliquer que vous devez utiliser className pour définir des classes sur le composant prend moins d'une minute et est facilement compréhensible. Expliquer pourquoi ils sont passés de className à class à chaque développeur prend beaucoup plus de temps et entraîne plus de frustration.

Tous les efforts requis pour un seul mot.
Cela ne changera rien au comportement de react.
Cela ne va pas booster le développement de react-dom.
Cela n'augmentera pas la productivité des développeurs travaillant plus d'une semaine avec React.
Ça va juste tout casser.

Pensez-y, est-ce que ça vaut vraiment le coup ?

J'utilise babel-plugin-react-html-attrs depuis des années et cela me sert bien, je ne pense pas que renommer className en class soit une bonne idée. C'est mieux réalisé par un plugin comme celui que j'ai mentionné.

N'y avait-il pas un plugin Babel pour gérer toute la situation " class v className " / " for v htmlFor " ?

J'espère qu'il est possible de prendre en charge les attributs html tels quels tout en maintenant la rétrocompatibilité avec les décisions de nommage déjà prises.

Le fait qu'il existe déjà des plugins babel pour effectuer la conversion est peut-être la preuve qu'il devrait être possible de le prendre en charge dans le transpiler JSX lui-même. Mais en faire une spécification officielle rendrait les choses beaucoup plus faciles et fiables pour tout le monde.

Je ne suis pas au courant des composants internes de React, donc je ne peux pas en dire beaucoup sur la faisabilité réelle. Exprimant seulement comment je pense que cela "devrait être" en termes de convivialité.

Veuillez reconsidérer className vs class . Comme il a été dit plus haut, le gain est quasi inexistant mais il y a de vrais inconvénients.

L'une étant que pour nous utilisant Haxe comme langage pour écrire des applications réactives, ce ne serait pas seulement un changement radical, mais nous empêcherait simplement d'écrire _tout_ application réactive.

class est un mot-clé réservé dans la plupart des langages de programmation, et nous ne pouvions tout simplement plus manipuler cet accessoire, rendant l'application de réaction presque impossible (bonne chance pour en créer un vrai sans manipuler les classes). Il en va de même pour htmlFor vs for , malheureusement (celui-ci est vraiment moche mais je suis reconnaissant qu'il existe).

Oh au fait, la possibilité de recherche... Imaginez que vous cherchiez "classe React" sur Google, vous obtiendrez des signaux mitigés : composants de classe React, attribut de classe React. Vous recherchez "React className" sur Google, vous obtiendrez une documentation obsolète (les personnes ont mentionné ci-dessus l'énorme quantité de travail de mise à niveau générée par ce changement en plus des mises à niveau de code).

L'objectif de ce projet est-il de générer plus de travail pour la communauté et plus de bruit et de signaux mixtes pour Internet ? J'espère que non.

Oui, l'écosystème Web et JavaScript a du mal à maintenir la rétrocompatibilité avec les erreurs stupides du passé, mais cette lutte pour la rétrocompatibilité est ce qui lui a permis de se développer à une telle échelle sans fragmentation majeure.

Je comprends qu'il n'y a pas de progrès sans changement, et j'ai moi-même adopté la devise du début de FB de casser les choses pour aller vite (avoir également un plan pour les réassembler à l'avance).

Si vous êtes si persistant que ce changement est vraiment nécessaire, indiquez simplement la véritable raison du changement. Cela ne peut pas être la chose "difficile à apprendre", cela semble trop superficiel pour la puissante équipe React Core. Vous devriez certainement avoir quelque chose en tête.

@sompylasar Je recherche habituellement className= ou className :, il semble que les deux fonctionnent également avec la classe.

Aussi, bonne chance pour le faire directement sur github =/

J'ai lu tous les commentaires ici. Je suis d'accord avec les changements, mais je ne suis pas sûr de class . La raison principale est que cela ne fonctionnera pas avec les plans pour JSX 2.0. sur la notation de raccourci (comme nous l'avons maintenant dans les objets).
Tout le reste semble être de très belles améliorations.
En attendant la décision finale :) Merci pour vos efforts incroyables les amis !

Dans un de vos commentaires, vous avez mentionné « si ça marche aujourd'hui, ça devrait marcher demain ». Gardez cela à l'esprit avant ma demande ;).

Je maintiens une bibliothèque d'interface utilisateur appelée RMWC https://jamesmfriedman.github.io/rmwc/ qui cible toutes les versions de React depuis la 15.4. J'ai pu maintenir une surface d'API unifiée, mais changer className en classe, onChange en onInput et la refonte du système d'événements rendront cela presque impossible à continuer.

Existe-t-il une possibilité d'une couche "compat" qui puisse traduire certaines de ces choses sous le capot ? Donc, je peux écrire dans n'importe quelle version réagir au feu mais continuer à fonctionner dans un temps d'exécution inférieur.

Sinon, je m'attends à ce que mon code bizarre devienne plus bizarre. 👀

si className doit vraiment changer en class , veuillez également changer htmlFor en for .
puisque class et for étaient invalides à l'origine lors de la déstructuration props .

Si React a sa propre API qui normalise de nombreux noms d'attributs pour créer une API cohérente, alors className est sûrement la solution idéale pour cela. Un apprentissage idiomatique supplémentaire en plus des idiomes camelCase, plus le fait qu'il correspond au nom de la propriété DOM (comme certains des autres attributs JSX) est sûrement bien par rapport à devoir le déstructurer comme un cas particulier à chaque fois que vous utilisez un objet d'accessoires avec lui.

J'ai l'impression que, jusqu'à présent, vous avez entendu beaucoup d'opinions vocales contre le statu quo ("pourquoi ne pouvons-nous pas avoir de cours ? !") alors que tous ceux qui étaient heureux de l'utiliser sont restés silencieux ; conformément au vieil adage selon lequel les gens sont beaucoup plus susceptibles de donner des critiques négatives que positives. Personnellement, je pense qu'une petite courbe d'apprentissage au-dessus de beaucoup d'autres est bien meilleure que le boîtier spécial de cet accessoire à chaque fois qu'il apparaît.

Je pense que j'aimerais voir un peu plus de démocratie autour de cela - je pense que ce changement très spécifique peut être fait par le comité (c'était essentiellement un pseudo comité qui vous a amené à envisager ce changement) - et je suis heureux d'être sur le côté perdant. Juste pour que cela affecte le moins de personnes au quotidien.

Ps tout le reste a l'air super d'ailleurs, en particulier les trucs de l'événement 👌🏻

en attente de nouvelles mises à jour

@gaearon Vaut-il la peine de considérer que votre propre exemple:

const { oneProp, twoProp, ...rest }  = this.props;

return (
  <div class={'something ' + rest.class} {...rest}/>
);

contient un bogue et ne fonctionnerait pas comme prévu ? Ce n'est peut-être pas aussi simple que "ne le déstructurez pas".

suis-je le seul à ne pas être préoccupé par le fait que la classe soit className ? Si vous me demandiez quels problèmes réagissaient, cela ne me traverserait même pas l'esprit.

Pourtant, les mises à jour sont gratuites et j'adore les cadeaux.

suis-je le seul à ne pas être préoccupé par le fait que la classe soit className ?

Je ne suis pas du tout inquiet pour la classe. Les bogues subtils avec IE11 vont être plus amusants (et je suis toujours plus que d'accord avec ces changements néanmoins)

Ce serait bien si la prise en charge des Passive Event Listeners était dans le cadre de React Fire, qui est une fonctionnalité importante sur mobile. #6436

Je suis d'accord. C'est certainement dans la portée de ce travail.

Hey @gaearon - tout d'abord merci.

Avez-vous envisagé de faire une enquête afin de recueillir des informations sur la façon dont les gens réagissent, sur les API utilisées et sur ce qui prête à confusion ?

Bien que React soit de loin ma pile de développement frontale préférée, je trouve qu'il y a quelques footguns lors de son apprentissage et de sa première utilisation. Je ne veux pas simplement exposer ce que les gens à qui j'ai enseigné ont personnellement trouvé déroutant.

Je l'ai trouvé utile dans les projets auxquels j'ai participé personnellement (Node, Bluebird, etc.).


En ce qui concerne ce que j'aimerais personnellement voir dans le noyau : j'aimerais un meilleur support d'injection de dépendance non globale plus simple, une gestion des événements meilleure et plus cohérente (dont vous discutez déjà).

Avez-vous envisagé de faire une enquête afin de recueillir des informations sur la façon dont les gens utilisent > réagir et quelles API sont utilisées et ce qui prête à confusion ?

Je pense que react-native a un canny.io Je n'avais pas réalisé que React ne l'était pas

Je maintiens une bibliothèque d'interface utilisateur appelée RMWC https://jamesmfriedman.github.io/rmwc/ qui cible toutes les versions de React depuis la 15.4. J'ai pu maintenir une surface d'API unifiée, mais changer className en classe, onChange en onInput et la refonte du système d'événements rendront cela presque impossible à continuer.

Existe-t-il une possibilité d'une couche "compat" qui puisse traduire certaines de ces choses sous le capot ? Donc, je peux écrire dans n'importe quelle version réagir au feu mais continuer à fonctionner dans un temps d'exécution inférieur.

Je comprends vos préoccupations (j'ai également écrit ma juste part de bibliothèques). Cependant, comme il y a tellement de compromis à faire pour changer quoi que ce soit, nous avons tendance à nous efforcer d'aider les gens à mettre à niveau plutôt que d'aider les gens à prendre en charge plusieurs versions. Cela ne signifie pas que nous ne le faisons pas du tout (nous avons publié un polyfill pour les auteurs de bibliothèques pour les modifications du cycle de vie dans la version 16.3), mais que nous n'optimisons pas pour ce cas d'utilisation.

Ma suggestion est de couper une nouvelle majeure lorsque nous coupons une nouvelle majeure si quelque chose est incompatible. Les utilisateurs peuvent continuer à utiliser les anciennes versions majeures de votre bibliothèque s'ils le souhaitent. Je sais que c'est plus d'efforts à maintenir, surtout si vous continuez à le développer, mais on peut se demander si une seule base de code hacky est meilleure que deux bases de code divergentes mais cohérentes.

@jamesmfriedman , il devrait être possible (et pas trop compliqué) de mettre à jour (automatiquement) avec un codemod) vers la nouvelle API, puis (dans le cadre du processus de construction) de transformer (encore une fois avec un codemod) vers l'ancienne API. Ensuite, expédiez les deux bundles et exigez-les dynamiquement en fonction de la version React.

C'est un peu de travail mais cela peut être fait une fois (en tant que plugin webpack ou script d'installation npm par exemple ?) et ne devrait pas être difficile. Je suppose que c'est le genre de chose à sortir une fois et à utiliser dans toutes les bibliothèques.

Comme une couche de compatibilité de temps de compilation spécifiquement pour les bibliothèques.

Je soutiens la suppression de htmlFor pour for.

Pensez-vous qu'une version bridge prenant en charge à la fois className et class serait une bonne idée ? Cela permettrait aux développeurs d'utiliser un code React tiers plus ancien, tandis que leur code propriétaire actuel peut être tourné vers l'avenir. Une fois les mises à jour tierces, il suffit de supprimer le package de pont pour obtenir un DOM React entièrement optimisé.

L'API React reste incohérente et casse d'autres hypothèses (pourquoi htmlFor pas pour etc.)

Je pense que vous avez raté la dernière phrase lorsque j'ai dit que for devrait également changer. Ensuite, je pense que nous serons parfaitement cohérents avec les "noms d'attributs en cas de chameau", à l'exception d'un ou deux attributs SVG rares. Ce que nous pouvons changer aussi.

N'y avait-il pas un plugin Babel pour gérer toute la situation « class v className » / « for v htmlFor » ?

Je vois pas mal de mentions à ce sujet, donc j'aimerais clarifier. Un plug-in Babel n'est pas l'endroit idéal pour effectuer cette conversion car il ne fonctionne pas dans des cas tels que

const props = {
   class: "foo"
}
<div {...props} />

Cela n'a pas non plus de sens que vous passiez class mais que vous obteniez className dans les props du composant. Ou, si le plug-in ne ciblait que les éléments de la plate-forme, il serait étrange que le remplacement button par un Button modifie la compilation de l'accessoire class .

L'utilisation du plugin Babel pour cela ne fait qu'obscurcir la sémantique du code que vous écrivez et conduit à plus de confusion. À mon avis, c'est une pire solution que de n'autoriser que className ou class .

Fait amusant : c'est ainsi qu'une très ancienne version du compilateur JSX fonctionnait. Ce comportement a été supprimé en raison de sa confusion.

Changements impressionnants. . .

Étonnante! Merci à tous les contributeurs d'avoir travaillé pour apporter des mises à jour aussi intéressantes.
Je n'avais aucune idée className > class était un si gros scandale. Personnellement je m'y suis habitué.

La taille réduite du bundle et le son du système d'événements amélioré sont vraiment prometteurs. Super content !

J'ai vraiment hâte de séparer les polyfills du système d'événements en tant que packages distincts.
Mais si className > class est trop radical, vous savez, React a un impact trop large.
Cela conduira-t-il à l'imprévu de nombreux systèmes ?

Laisser tomber un tiers de React DOM serait bien.

Ce sera formidable d'utiliser React dans le développement d'applications Web.

Ce serait également bien que l'espace de noms réagisse à des props spécifiques comme key et ref . par exemple

<Foo @key="foo" @ref={callback} prop="hi" />

cela a été discuté ici - https://github.com/facebook/jsx/issues/66

@elado Bien que cela puisse être quelque chose que nous voulons faire à l'avenir, je pense que c'est hors de portée car cela affecte une API non spécifique à DOM.

Bien que ce soit excitant, en particulier la réduction de la taille du paquet qui est toujours la bienvenue. Mon inquiétude est que les gens de Facebook sous-estiment l'inertie, la douleur et la fragmentation que les changements d'API peuvent causer à l'écosystème et à la communauté.

Il est vrai qu'ils doivent s'inquiéter d'un grand nombre de composants chez FB, mais l'avantage qu'ils ont, et je suppose ici, est leur dépendance minimale vis-à-vis des bibliothèques de réaction open source externes, car ils ont probablement construit la plupart de leurs composants en interne. Pour les autres personnes qui utilisent beaucoup de bibliothèques open source, il a fallu beaucoup d'efforts, d'attente et de frustration pour sortir Proptypes de nombreuses bibliothèques (et je parle d'une expérience réelle de mise à niveau d'une grande base de code de réaction). Agir rapidement et casser des choses peut ne pas s'appliquer aux personnes qui souhaitent créer une entreprise stable avec des ressources limitées.

J'aime vraiment réagir, l'API est simple et personnellement, il ne m'a pas fallu de temps pour apprendre et m'adapter à sa syntaxe. Ainsi, j'exhorte vraiment le mainteneur à évaluer soigneusement les avantages / inconvénients de tout changement de rupture à l'échelle de l'écosystème et à réfléchir de manière pragmatique si le changement justifie de forcer l'ensemble de l'écosystème à être réécrit.

En dehors de cela, j'apprécie vraiment l'effort de construction, de maintenance et de mise à niveau de React, et la passion des ingénieurs derrière :)

Ces futures {...mises à jour} sont 🔥

className -> class : Je ne pense pas que ce soit une situation rare lorsque l'attribut de classe est défini en dehors de la déclaration JSX/object. Dans de telles situations, nous devrons utiliser des noms différents pour la même chose, ce qui introduira des incohérences, augmentera la complexité du code et la charge cognitive.
La modification suggérée ne supprimera pas l'incompatibilité de nom d'attribut/prop de nos bases de code - elle existera quelque part en raison des limitations de syntaxe ou lorsque vous travaillez avec le DOM natif. C'est une bonne chose que nous ayons "normalisé" (et bien établi à ce stade) une solution de contournement pour ce problème de nommage.
Actuellement, className peut être utilisé de manière cohérente partout, faisant toujours référence à la même chose - même lorsque vous travaillez avec le DOM natif. En fait, la réaction peut être littéralement le seul endroit où nous serons obligés d'utiliser class pour faire référence à l'attribut de classe.
className semblait assez inutile et un peu déroutant dès le début, mais s'est avéré assez pratique plus tard et relativement facile à s'y habituer.

Je supprimerais également l'objet supplémentaire { __html } pour dangerouslySetInnerHTML car cela semble vraiment inutile, mais cela ne vaut peut-être pas les problèmes liés à la migration (et peut-être sans rapport avec ce problème).

Alors que les autres changements génèrent beaucoup moins d'émotions, ils sont beaucoup plus intéressants et importants, alors merci à l'équipe fb pour l'effort.

Plus il y a de modifications radicales, plus la mise à niveau des applications utilisateur réelles prendra du temps. Personnellement, je suis déjà assez loin derrière le dernier plus grand React (ce qui m'attriste), car les versions précédentes de React ont des choses cassées qui nécessitent ensuite des bibliothèques dont je dépends pour la mise à niveau, ce qui introduit alors un retard.

Idéalement, j'aimerais être dans le scénario qui :

  • La bibliothèque Downstream React réécrit le code sur la nouvelle version, introduisant un bogue pour mon cas d'utilisation
  • React ajoute une nouvelle fonctionnalité intéressante / une réduction de bundle
  • L'ancienne version de la bibliothèque reste utilisable sur le nouveau React
  • Yay, je peux utiliser la nouvelle fonctionnalité juste après le lancement de React et attendre que la bibliothèque corrige le bogue

En pratique c'est plutôt :

  • La bibliothèque réécrit le code, introduisant un bogue
  • React publie un nouveau changement de rupture
  • L'ancienne bibliothèque ne fonctionne plus
  • La nouvelle bibliothèque est éventuellement mise à jour
  • Le bug peut encore être présent
  • Je suis coincé sur React obsolète plutôt que (pour citer Ken Wheeler) "la nouvelle hotness" depuis longtemps.
  • Je me sens triste :(

Du point de vue du "code d'expédition", chaque mise à niveau majeure devient une énorme dette technique ennuyeuse qui implique de mettre à jour toutes les dépendances, de tout re-tester, puis de rechercher de nouveaux bogues pour voir s'il existe une solution de contournement. À moins qu'il n'y ait une vulnérabilité critique ou qu'il ne soit vraiment pas pratique de faire quelque chose (et que la barre est haute), elle est dépriorisée.

Malheureusement, bien qu'il ait abandonné son paradigme 0.x et malgré ses efforts pour être une bibliothèque Web principale, React produit toujours des numéros de version, ce qui signifie que beaucoup de temps est passé à rester immobile.

Fondamentalement, ce que je dis, c'est, s'il vous plaît, s'il vous plaît, essayez de planifier une API qui permette aux futurs grands changements de ne pas se casser.

(De plus, la chose IE11 est triste parce que vous dépréciez un navigateur qui n'est pas EOL - dernière version il y a 52 jours. Je pense que l'équipe React trouvera que cela ne fait que pousser le travail à l'équipe Facebook et à toutes les équipes de bibliothèque externes et internes pour l'atténuer au lieu).

@urugator

Je supprimerais également l'objet supplémentaire { __html } pour dangereusementSetInnerHTML car il semble vraiment inutile

Ceci est intentionnellement conçu pour être explicite et difficile à utiliser accidentellement. S'il est supprimé, toutes les données non nettoyées peuvent accidentellement être transmises à dangereusementSetInnerHTML.

@philipwhiuk

Fondamentalement, ce que je dis, c'est, s'il vous plaît, s'il vous plaît, essayez de planifier une API qui permette aux futurs grands changements de ne pas se casser.

Des changements de rupture sont nécessaires pour améliorer la technologie, et React le fait de manière responsable avec des lots peu fréquents de changements de rupture. Sans casser les changements comme la suppression de componentWillReceieveProps, nous n'aurions pas de grandes choses comme React Suspense, et les logiciels de la communauté seraient plus difficiles à maintenir avec les anciennes API qui resteraient pour toujours. Si vous mettez à niveau une version majeure à la fois, tout devrait bien se passer.

De plus, la chose IE11 est triste parce que vous dépréciez un navigateur qui n'est pas EOL - la dernière version il y a 52 jours.

Personne ne déprécie IE 11. La version actuelle de React nécessite en fait des polyfills pour certaines fonctionnalités d'IE 11, de sorte que les modifications suggérées auraient probablement à peu près le même effet sur le développement d'IE 11. https://reactjs.org/docs/javascript-environment-requirements.html

Je supprimerais également l'objet supplémentaire { __html } pour dangereusementSetInnerHTML car il semble vraiment inutile

@urugator - Pour ce que ça vaut, en interne chez Facebook, l'utilisation la plus courante de __html consiste à insérer du code HTML rendu par le serveur dans une arborescence de composants React. Pour ce cas d'utilisation, nous construisons les objets __html côté serveur, et avons des règles lint contre le fait côté client. Côté serveur, nous avons des méthodes qui sérialisent XHP en objets avec des propriétés __html . Cela garantit que nous n'introduisons aucune faille de sécurité nulle part, car XHP est très similaire à JSX (c'était en fait l'inspiration principale de JSX) et dispose également d'une protection XSS.

Essentiellement, les objets __html marquent une chaîne de code HTML dont nous savons qu'elle a été nettoyée quelque part et qu'elle peut être insérée directement dans le DOM en toute sécurité. Une chaîne brute est plus difficile à gérer - Comment savoir si elle a été nettoyée ou si quelqu'un a accidentellement renvoyé une entrée utilisateur brute (et donc introduit un trou XSS) ?

Alors oui, c'est intentionnellement difficile à utiliser, car il ne devrait pas y avoir beaucoup de cas d'utilisation dans la plupart des applications, et les cas d'utilisation doivent être raisonnablement contenus. En règle générale, vous ne devriez pas construire l'objet __html directement dans votre composant React, vous devriez plutôt avoir une fonction qui le renvoie (voir comment la documentation utilise une fonction createMarkup : https://reactjs. org/docs/dom-elements.html#dangerouslysetinnerhtml)

Mon inquiétude est que les gens de Facebook sous-estiment l'inertie, la douleur et la fragmentation que les changements d'API peuvent causer à l'écosystème et à la communauté.

Merci d'avoir soulevé cette question. Je comprends tout à fait où vous voulez en venir. Mais je tiens à souligner que la majorité des membres de l'équipe React utilisaient eux-mêmes React en dehors de Facebook avant d'être embauchés - souvent sur de grandes applications. Je pense donc que cela nous aide à comprendre les types de problèmes qui affectent nos utilisateurs open source. J'utilise React depuis deux ans et je me souviens très bien de la fragmentation causée par exemple par le changement de contexte parent/propriétaire. La clé était d'avoir une bonne stratégie de migration - et il en va de même pour tous les changements ci-dessus.

Il est vrai qu'ils doivent s'inquiéter d'un grand nombre de composants chez FB, mais l'avantage qu'ils ont, et je suppose ici, est leur dépendance minimale vis-à-vis des bibliothèques de réaction open source externes, car ils ont probablement construit la plupart de leurs composants en interne.

Cela a toujours été vrai pour le côté produit du développement. Cependant, depuis que Yarn a été créé et intégré à notre référentiel Web, nous avons vu un nombre croissant de composants tiers utilisés dans les pages d'outils internes - qui en eux-mêmes ont une surface beaucoup plus grande que les produits de consommation Facebook. Nous aurons donc besoin d'une stratégie de migration progressive dans des packages tiers également.

Contrairement à de nombreuses autres entreprises, nous utilisons la même version de React sur l'ensemble de la base de code. Nous avons donc également des défis uniques (par exemple, nous ne pouvons pas simplement "attendre" avec la mise à niveau de certains produits). Cela va certainement ajouter plus de pression sur nous pour avoir une bonne stratégie de migration et servir de test de résistance.

Pour les autres personnes qui utilisent beaucoup de bibliothèques open source, il a fallu beaucoup d'efforts, d'attente et de frustration pour sortir Proptypes de nombreuses bibliothèques (et je parle d'une expérience réelle de mise à niveau d'une grande base de code de réaction). Agir rapidement et casser des choses peut ne pas s'appliquer aux personnes qui souhaitent créer une entreprise stable avec des ressources limitées.

Au cas où vous seriez curieux, nous avons encore du code comme

React.PropTypes = require('prop-types')
React.createClass = require('create-react-class')

dans notre base de code parce que nous ne pouvons pas non plus nous permettre de migrer complètement vers une "table rase". Mais les personnes qui commencent avec React aujourd'hui, ainsi que les parties plus modernes de notre base de code, n'ont pas à porter ce poids. C'est un peu comme ça que nous y pensons - nous voulons choisir de meilleures valeurs par défaut pour les nouveaux utilisateurs de React, mais avoir une bonne histoire de migration pour nous-mêmes et pour tout le monde, même si certaines parties peuvent être piratées.

Je n'ai peut-être pas communiqué cela assez clairement, donc je m'excuse. Tout changement important nécessitera une stratégie de migration sophistiquée et bien exécutée qui prend en compte le fait que les bibliothèques tierces prendront beaucoup de temps à se mettre à jour, que différentes versions devront peut-être coexister, etc. Par exemple, avec class le le plan n'est pas seulement de le changer du jour au lendemain. Si nous voulons le faire, nous voudrons être intelligents sur la façon de le déployer - éventuellement avec une période de grâce où nous autorisons les deux, ou un assistant pour le rendre plus facile à faire, puis supprimer progressivement l'ancien nom . Je n'ai pas encore de stratégie précise, mais il est clair que le changement est tout simplement impossible sans une bonne stratégie, tant pour nous que pour vous. C'est quelque chose que nous prenons très au sérieux.

(De plus, la chose IE11 est triste parce que vous dépréciez un navigateur qui n'est pas EOL - dernière version il y a 52 jours. Je pense que l'équipe React trouvera que cela ne fait que pousser le travail à l'équipe Facebook et à toutes les équipes de bibliothèque externes et internes pour l'atténuer au lieu).

Je ne comprends pas à quoi vous faites référence. Je n'ai dit nulle part où IE11 devenait "obsolète".

Mon message dit seulement que nous pourrions avoir besoin de plus de polyfills que maintenant pour des navigateurs comme IE11. React nécessite déjà des polyfills dans IE11. Je ne dis pas que nous voulons le casser - il a encore de nombreux utilisateurs - mais que vous devrez inclure plus de polyfills si vous voulez que cela fonctionne. Cela me semble tout à fait juste.

De plus, nous ne pouvons pas "pousser le travail" vers d'autres équipes de Facebook. Si nous cassons quelque chose, c'est à nous de le réparer. C'est pourquoi nous nous soucions tant des stratégies de migration - nous devons généralement les exécuter nous-mêmes.

Re : le reste de votre commentaire - nous n'apportons absolument pas de modifications radicales pour le plaisir de le faire. En fait, nous essayons très, très fort d'éviter les changements de rupture. De nombreuses parties de React sont compliquées et difficiles à maintenir, mais nous les gardons pour la seule raison que nous essayons de prendre en charge les API héritées même si elles ont été explicitement marquées comme instables. Cependant, à un moment donné, le poids des problèmes s'accumule et nous devons faire table rase pour avancer et les résoudre. Les problèmes dans mon post OP sont exactement ce genre de problèmes. Ils ne vaudraient pas la peine de faire un changement par eux-mêmes. Mais combinés, nous pensons qu'ils en valent la peine.

Je ne comprends pas pourquoi les gens sont si négatifs à ce sujet. Ne mettez pas à niveau tant que vos dépendances ne le font pas ?

Le problème des mots clés pour class vs className et for vs htmlFor n'est-il pas quelque chose que le compilateur jsx peut gérer pour remplacer les mots réservés ?

Je ne serais vraiment inquiet que si les changements sont suffisamment importants pour que les résultats de la recherche donnent des réponses obsolètes ... Comme la douleur angulaire 2+ introduite lors de la recherche de "angular -angularjs -angular1.x" etc.

A part ça, j'accueille tous les changements!!!

@gaearon

Tu as dit

"Nous devrons peut-être supprimer la compatibilité avec certains navigateurs plus anciens"

C'était la partie de compatibilité des chutes avec laquelle j'avais un problème, pas la partie polyfill suivante. Revenir à l'âge des ténèbres était mon souci.

Concernant le processus. N'est-ce pas ce genre de "problème" pour lequel le processus RFC a été conçu ?

C'était la partie de compatibilité des chutes avec laquelle j'avais un problème, pas la partie polyfill suivante. Revenir à l'âge des ténèbres était mon souci.

Je parlais d'IE10 et des versions antérieures. J'ai spécifiquement noté que nous voulons continuer à prendre en charge IE11 - je pense qu'il représente environ 3% de notre trafic, ce qui est bien plus que le seuil de 1% où nous le considérons comme trop ancien.

Concernant le processus. N'est-ce pas ce genre de "problème" pour lequel le processus RFC a été conçu ?

Nous publierons des RFC lorsque les choses seront plus étoffées. Une grande partie de cela nécessite une exploration, une expérimentation et des tests réels pour déterminer ce que nous pouvons et ne pouvons pas faire, et quelles stratégies de migration nous pourrions utiliser. Nous n'avons pas assez de détails pour le moment pour même commencer à penser aux RFC (qui devraient inclure une stratégie de migration complète).

Ok merci pour la précision !

@gaearon

Il est plausible que nous nous débarrassions complètement des événements synthétiques.

Comment cela fonctionnerait-il avec event.currentTarget pointant vers l'élément sur lequel l'écouteur d'événement est attaché, ce qui dans le cas natif signifie toujours document - ou la racine React une fois que React passe à cela ?

React ne consiste pas seulement à définir des propriétés

(...)

Mon point ici est que si React utilise des propriétés ou des attributs en interne est un détail d'implémentation

Pourquoi est-ce un détail d'implémentation alors que cela peut influencer ce qui se passe dans le DOM ? À moins que cela ne fasse référence qu'aux propriétés qui sont reflétées d'une manière ou d'une autre dans les attributs (et inversement) comme class / className .

Je pense que la confusion autour du traitement de class / className est liée au fait que le fait que React utilise une propriété ou un attribut est considéré comme un détail d'implémentation. J'ai une expérience angulaire et quand j'ai commencé à utiliser React, c'était le plus gros piège pour moi - dans Angular, la séparation entre les attributs, les propriétés et les gestionnaires d'événements est claire directement à partir de la syntaxe et je ne savais pas si les accessoires sur les éléments DOM étaient définis par React comme propriétés ou attributs.

Comment cela fonctionnerait-il avec event.currentTarget pointant vers l'élément sur lequel l'écouteur d'événement est attaché, ce qui dans le cas natif signifie toujours document - ou la racine React une fois que React bascule vers cela ?

Je ne sais pas encore. :-) Nous verrons ce que nous pouvons faire. Il est tout à fait possible que certaines de ces choses ne fonctionnent pas ou se déroulent différemment. Ce plan n'est qu'un aperçu des choses que nous prévoyons d'examiner et de la vision unificatrice pour celles-ci.

Pourquoi est-ce un détail d'implémentation alors que cela peut influencer ce qui se passe dans le DOM ? À moins que cela ne fasse référence qu'aux propriétés qui sont reflétées d'une manière ou d'une autre dans les attributs (et inversement) comme class/className.

Pour la majorité d'entre eux, il n'y a pas de différence observable du point de vue de l'utilisateur lequel utiliser. Je pense que la plupart d'entre eux sont reflétés (bien que je me trompe peut-être).

J'ai un arrière-plan angulaire et quand j'ai commencé à utiliser React, le plus gros problème pour moi - dans Angular, la séparation entre les attributs, les propriétés et les gestionnaires d'événements est claire directement à partir de la syntaxe et je ne savais pas si les accessoires sur les éléments DOM étaient définis par React en tant que propriétés ou attributs.

J'apprécie votre point de vue. Cependant, dans la pratique, cette différence n'est souvent pas pertinente pour la plupart des éléments DOM et il est discutable qu'apprendre les tenants et les aboutissants de celui à utiliser, et devoir toujours y penser, est en fait précieux pour le développement de produits au quotidien. Je pense que le degré auquel les gens les confondent témoigne du fait que ce n'est pas vraiment pertinent pour eux.

(Il y a des cas où cela devient beaucoup plus pertinent, comme avec des éléments personnalisés. Mais même là, prendre en charge les deux de manière égale est tout aussi déroutant car vous devez choisir lequel utiliser. Cela a été débattu ailleurs, donc j'aimerais éviter de sauter dans ce débat à nouveau - nous avons des propositions de gens comme @robdodson et nous les examinerons.)

@Daniel15
Sans les politiques mentionnées (qui, je pense, ne sont mentionnées nulle part ailleurs), le wrapper d'objet supplémentaire ne le rend en aucun cas plus sûr.
Je pense que l'utilisateur est suffisamment averti de l'utilisation dangereuse via dangerouslySetInnerHTML . C'est le moment où l'utilisateur est obligé de vérifier la documentation, d'examiner les implications et de prendre la décision.
La nécessité d'envelopper la chaîne (éventuellement non désinfectée) dans un objet/une fonction quelconque ne le fera pas reconsidérer ou désinfecter la valeur enveloppée.
Si cela fonctionnait de cette façon, alors peut-être { __html } n'est pas assez compliqué et que [{ _html: { __html }] le rendrait encore plus sûr - combien de fois devons-nous déclarer que quelque chose est dangereux pour le rendre sûr ?

Avec les informations que vous avez fournies, je comprends le raisonnement, mais je pense qu'il ne s'applique actuellement à personne en dehors de Facebook, car nous n'avons aucune idée de la règle " { __html } représente le code HTML épuré".
J'ai toujours pensé que c'était juste une autre obstruction dans l'API. Merci d'avoir pris le temps et d'avoir fait la lumière là-dessus, cela a plus de sens maintenant.

Il ne s'agit pas seulement de le rendre plus complexe, il s'agit d'empêcher que des données non nettoyées soient utilisées accidentellement.

J'adore la façon dont la réaction est si opiniâtre par la communauté. Félicitations à vous les gars pour tout entendre et en tirer le meilleur parti.

J'aime la façon dont tout le monde pense que les changements qui arrivent ici ou qui sont venus sur React dans les dernières versions étaient "casseurs". Ces personnes n'ont clairement pas expérimenté l'Angular 2 > 3 > 4 fois.

J'adore les changements. Personnellement, cela ne me dérange pas className et la déstructuration class pourrait devenir un problème. Mais j'aimerais voir ce que vous allez trouver.

Je voudrais demander de garder cette discussion sur le sujet. Que vous trouviez utile ou non de souiller du code HTML dangereux est intéressant, mais n'est pas lié au problème.

j'aime réagir

C'est une occasion parfaite d'aider les nouveaux développeurs à réagir et à se sentir mieux accueillis. Je suis très heureux que cela se produise.

Le simple fait de laisser les gens utiliser la classe n'a aucun effet négatif, sauf que cela ne fonctionne pas avec la déstructuration et le coût de la migration.

@gaearon Lancer 2c mais ces deux négatifs semblent aussi gros ou plus gros que le négatif actuel (un petit coût ponctuel d'apprentissage de la classe => className vs toujours éviter la déstructuration + coût de migration au niveau de l'écosystème).

Réagis :coeur:

faisant écho à @natew ci-dessus :

@gaearon Lancer 2c mais ces deux négatifs semblent aussi gros ou plus gros que le négatif actuel (un petit coût ponctuel d'apprentissage de la classe => className vs toujours éviter la déstructuration + coût de migration au niveau de l'écosystème).

Quoi qu'il en soit, quelle est la motivation derrière le passage de className à class ?
Autant que je sache, votre commentaire se résume à deux arguments (veuillez me corriger si je me trompe):

plus proche conceptuellement de ce que la plupart des gens attendent

Ok, mais ajouter Name est le plus petit des obstacles. Apprendre à utiliser className était la partie la plus simple de l'apprentissage de React. C'est une petite bizarrerie qui n'a aucun inconvénient - en fait, cela résout en fait un problème avec quatre personnages. Et il a beaucoup moins de surcharge cognitive que n'importe laquelle des alternatives de déstructuration fournies.
Imaginez apprendre à quelqu'un à styliser son premier composant React avec

function Button({ color, ...rest }) {
  const buttonClass = rest.class +  ' Button-' + color;
  return <button {...rest} class={buttonClass} />
}

Ma tête de noob aurait explosé.
Je pense que lorsqu'ils interagissent avec une API, les gens s'attendent à ce que l'API fournisse des solutions. ClassName est une solution intégrée. La classe est un problème intégré.

moins de frappe

Bruh, c'est quatre caractères 8^) . De plus, même si nous déstructurons class beaucoup moins fréquemment que nous n'utilisons actuellement className , c'est beaucoup plus typé quand nous le faisons. J'aurai donc tapé 4 caractères de moins 12 fois mais ajouté 50 caractères de plus à chacune des fois où j'ai détruit class ? C'est tout simplement idiot.

Y a-t-il une autre raison impérieuse pour ce changement que j'ai raté ?
La motivation est-elle une sorte de souci de conformité avec les attributs/propriétés DOM ?
Cela me semble un argument beaucoup trop académique. La plupart des gens ne sont pas très conscients de ces détails de mise en œuvre et je ne pense pas qu'ils aient besoin de l'être.

Est-ce que s'il était publié aujourd'hui, React autoriserait class au lieu de passer à className ?
Je pense que ce n'est pas pertinent.
React n'était pas open source aujourd'hui et s'il était/serait open source dans un an, un ensemble de décisions différent pourrait être pris à ce moment-là.
Parfois, il vaut mieux s'en tenir à la cohérence que d'essayer d'aplanir chaque ride.

Et si React avait utilisé la classe depuis le début, nous nous serions habitués à déstructurer la classe et à la réaffecter à className, mais quiconque se présenterait avec un PR pour changer la classe _to_ className serait salué comme un sauveur.

Enfin, je veux juste dire que je ne m'attendais pas à être aussi énervé à ce sujet, alors je m'excuse si quelque chose est apparu comme grossier, insultant ou accusateur. Je suis reconnaissant pour tout le travail que vous faites sur React et pour toutes les connaissances que vous déposez sur Twitter - j'ai utilisé vos tweets pour défendre certaines réponses que j'ai données lors d'entretiens.

Je prie dan.church pour que vous changiez d'avis.

Je suis très heureux que React puisse être continuellement mis à jour. En tant que développeur utilisant React, je ne veux pas le voir dépassé par Vue. Mais le processus de className-> class doit être pénible.

Je ne suis pas contre le renommage className -> class pour le copier-coller, mais il n'y a pas de motivation claire pour l'instant. className existe dans le DOM alors qu'il y a des noms d'accessoires réservés qui sortent de nulle part comme htmlFor . J'ai l'impression que ceux-ci devraient être prioritaires lorsqu'il s'agit de renommer et que c'est probablement moins envahissant d'un changement qui peut également servir de test.

@sonhanguyen htmlFor est également le nom officiel de l'API Web : https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor

@allan2coder au lieu de l'envelopper dans un tableau, enveloppez-le dans <React.Fragment> ou <> .

@ allan2coder Veuillez également garder ce fil sur le sujet, vous pouvez poser des questions en déposant un problème séparé si vous le souhaitez.

J'aimerais attirer l'attention sur patch-package qui est un package qui permet de corriger assez facilement vos dépendances (par exemple, pour les empêcher d'utiliser des API React non prises en charge). Certes, cela est plus utile pour le code d'application que pour le code de bibliothèque, mais je pense que cela devrait aider à répondre à certaines des préoccupations de @philipwhiuk .

J'ai hâte de.

  • Migrez de onChange vers onInput et ne le remplissez pas pour les composants non contrôlés.

Pour les mots ci-dessus, je suis curieux de savoir si l'événement onChange sera utilisé à proximité de l'événement natif ou ne sera pas utilisé à l'avenir ?

@MuYunyun

Sur la base du libellé, ils ne prévoient pas de conserver le comportement actuel de onChange. Cela n'aurait pas beaucoup de sens. Réagir comme les autres bibliothèques modernes ne sera pas une couche de compatibilité de navigateur, et ne devrait pas l'être.

Le onChange actuel émule onput + quelques autres cas. Cela n'a aucun sens étant donné qu'un événement de modification existe déjà dans le DOM et qu'il n'a pas la même sémantique : https://developer.mozilla.org/en-US/docs/Web/Events/change

@jxub

Un peu décalé mais c'est un peu triste que personne (pour autant que je sache) n'ait eu l'idée de créer un transfomer html/css/svg -> jsx afin de faciliter les migrations vers React avec autant de changements triviaux pour mapper les attrs HTML à Réagissez les accessoires. Tant d'heures de travail perdues à effectuer principalement la recherche et le remplacement :(

Je ne connais pas les autres éditeurs, mais IntelliJ IDEA (et WebStorm, PhpStorm, etc.) effectue cette transformation lorsque vous collez un code HTML dans JS.

Un peu décalé mais c'est un peu triste que personne (pour autant que je sache) n'ait eu l'idée de créer un transfomer html/css/svg -> jsx afin de faciliter les migrations vers React avec autant de changements triviaux pour mapper les attrs HTML à Réagissez les accessoires. Tant d'heures de travail perdues à effectuer principalement la recherche et le remplacement :(

Il existe réellement mais il est assez ancien et pas tout à fait correct : https://magic.reactjs.net/htmltojsx.htm

Nous devrions relancer cet effort. Si vous voulez aider, veuillez faire : https://github.com/reactjs/reactjs.org/issues/484. Jusqu'à présent, personne n'a proposé d'aider et de suivi.

Il existe réellement mais il est assez ancien et pas tout à fait correct : https://magic.reactjs.net/htmltojsx.htm

Je l'ai utilisé une tonne de fois auparavant - il est très courant de l'utiliser lors de l'externalisation de certains composants à des personnes qui connaissent HTML/CSS mais pas JavaScript.

Il suffit donc de donner des commentaires sur le fait qu'il s'agit d'un outil utile que les gens utilisent dans la pratique. Il existe également d'autres convertisseurs en ligne.

Un problème avec cette approche est qu'elle n'est qu'à sens unique (seulement migrer _pour_ réagir). Ce problème n'est pas particulier à React.

J'espère que cela rendra les choses beaucoup plus faciles...

Un problème avec cette approche est qu'elle n'est qu'à sens unique (migrer uniquement pour réagir). Ce problème n'est pas particulier à React.

Pourquoi? Cela devrait être encore plus facile dans l'autre sens - lancez simplement ReactDOMServer.renderToString .

Attendre patiemment la sortie

@gaearon

Pourquoi? Cela devrait être encore plus facile dans l'autre sens - exécutez simplement ReactDOMServer.renderToString.

Ok, donc pour le contexte, le problème discuté est le suivant : je veux que les personnes qui écrivent html/css et ne connaissent pas assez bien JavaScript pour travailler sur le code JS puissent travailler sur le balisage/style/mise en page des composants.

Une façon de le faire maintenant est de les faire développer en html/css et d'utiliser htmltojsx. Cela fonctionne plutôt bien pour moi.

Le problème est que je dois maintenant maintenir moi-même chaque changement de balisage/style/mise en page dans React.

Si j'appelle ReactDOMServer.renderToString en effet, j'obtiendrais du HTML statique, mais ce HTML manquerait tout le code du composant réel, il n'est donc pas possible de le donner aux personnes de l'interface utilisateur et d'utiliser leur sortie car je devrais tout réécrire ma logique.

Des choses comme react-sketchapp sont une bonne solution possible au problème, mais j'espère une approche plus générique me permettant de le faire tout en utilisant du html/css normal. Par exemple - via une certaine forme de métadonnées et en conservant les identifiants de réaction sur les éléments.

Je comprends tout à fait que ce n'est pas à la portée du noyau ReactDOM, mais c'est définitivement dans son domaine et c'est un problème intéressant.

Ce n'est pas une priorité - je voulais surtout juste expliquer pourquoi htmltojsx est utile à certains d'entre nous même en dehors du contexte d'une migration :)

Je veux que les personnes qui écrivent html/css et ne connaissent pas suffisamment JavaScript pour travailler sur le code JS puissent travailler sur le balisage/style/mise en page des composants.

Quelle est l'ampleur du problème et à quel point serait-il difficile de leur apprendre un peu de JSX ? Les modifications doivent de toute façon être examinées par un ingénieur averti de React.

Désolé si cela devient trop hors sujet, mais je pense que HTML/CSS ne suffit pas de nos jours.

( @gaearon , n'hésitez pas à le cacher s'il devient bruyant car il s'agit d'une réponse au commentaire OT déjà léger ci-dessus)

Quelle est l'ampleur du problème et à quel point serait-il difficile de leur apprendre un peu de JSX ? Les modifications doivent de toute façon être examinées par un ingénieur averti de React.

Eh bien, cela nécessiterait ce qui suit:

  • Ne travaillez qu'avec des sous-traitants qui connaissent votre pile React actuelle. Il est beaucoup plus difficile de trouver des personnes qui apprendront les composants de style
  • Installez Node (npm), votre pile (React, webpack, etc.) et tout ce qui est nécessaire pour l'exécuter sur l'ordinateur de chacun des utilisateurs de l'interface utilisateur et maintenez-le à jour.
  • Apprenez-leur la programmation de base et JavaScript, apprenez à travailler avec les outils de développement, les erreurs de console, etc.
  • Apprenez-leur React, quelle est sa syntaxe, des trucs comme className , ce que signifie key etc.
  • Ne travaillez qu'avec des sous-traitants et des indépendants qui sont prêts à travailler de cette façon plutôt que de produire du HTML/CSS. Cela rend généralement les choses plus chères.

Maintenant, comme mentionné ci-dessus, des choses comme react-skeptchapp sont un moyen utile de rendre cela plus accessible et plus facile pour les gens de l'interface utilisateur - mais cela leur demande encore beaucoup d'apprendre.

Je comprends tout à fait pourquoi vous demandez cela et je ne suis pas sûr que ce soit un problème courant (je suppose que c'est le cas). Quoi qu'il en soit, je ne pense pas que ce soit dans le cadre de l'avenir du noyau de ReactDOM.

C'est assez hors sujet :-) Continuons cette discussion sur Twitter ou ailleurs.

"Le comportement pour lequel vous voyez un outil utilisé est un comportement que l'outil encourage"
~ Gary Bernhardt

La façon dont React est utilisé, pour la plupart ne faisant pas partie de l'API de React, entraîne un grand nombre de pièges qui entraînent des discussions comme celle-ci où tout le monde est confus et frustré. Est-ce que l'utilisation d'un mot-clé réservé tel que class est mauvaise à cause de javascript, html ou réagit elle-même ?

Pour en revenir aux modifications apportées en 16.3 (si je me souviens bien), la bibliothèque se comporterait désormais différemment en acceptant tout attribut passé aux éléments html natifs rendus par le vdom, je me souviens très bien que la plupart de ma base de code était désormais en proie à des bogues car du comportement que nous avons eu en mettant en œuvre ce modèle clairement mauvais

<div {...this.props} />

Je dois donc dire que je suis assez déçu que Dan suggère que nous continuions à diffuser ce terrible code sur toutes les bases de code.

Tout d'abord, il n'y a aucune garantie dans le contenu de props , mais à la première fois, les éléments html natifs ne feront presque toujours pas ce qu'on attend d'eux si vous leur passez les mauvais accessoires, mais en même temps il est considéré comme sûr de propager les accessoires parents jusqu'aux composants enfants, mais en réalité, c'est terriblement paresseux

<Child {...props} />

const Child = (props) => <div {...props} />

Parfois, vous ne savez même pas ce que vous rendez et ce problème devient encore plus difficile à gérer. Il est également extrêmement difficile de typer ce type de composants à l'aide de systèmes de types, car cela signifierait que la plupart des composants doivent implémenter un certain nombre d'interfaces aléatoires qu'ils doivent partager entre eux, c'est un trou de lapin profond dans lequel descendre.

Si une réécriture pour réagir est faite pour résoudre ce problème, je m'attendrais à ce que les concepteurs derrière elle réalisent le mal que ces mauvais modèles causent à la base de code au lieu de doubler les mauvaises décisions.

Nous devons nous rappeler que jsx est construit sur javascript, et utiliser les "idiosyncrasies" de javascript comme excuses pour entrer délibérément en conflit avec le langage dans l'utilisation de mots-clés est un mauvais premier pas vers la réparation de l'API, je suggérerais qu'au lieu de commencer une guerre contre la langue tu t'en éloignerais complètement

@gaearon longtemps! :) (ps. désolé pour tl;dr à venir)

Quoi qu'il en soit, je voulais juste donner un aperçu de ce que j'ai appris de mes propres aventures. J'ai créé mon propre dérivé React "minimal" que j'utilise maintenant pour les applications critiques en termes de performances/fonctionnalités. Ce n'était au départ qu'une expérience amusante, mais je voyais des améliorations de performances supérieures à + 300% dans des cas réels pour le rendu initial / la mise à jour / la suppression, y compris de nombreux autres avantages. C'est sans utiliser un gestionnaire d'événements regroupés aussi.

IIRC une grande partie de cela vient simplement de ma propre bibliothèque en contournant toute la logique des accessoires React et en alimentant simplement les attributs directement dans setAttribute, les styles directement dans style.setProperty, les écouteurs directement dans addEventListener, etc. Ainsi, l'interface d'élément DOM de base ressemble à ceci `{attributes : {}, style : {}, listeners : {}, className : "", ...}, c'est plus verbeux mais l'interface est maintenant petite et triviale à implémenter et est extrêmement rapide. C'est probablement trop extrême pour vous, mais cela m'a très très bien servi.

Quelque chose que j'ai fait aussi est de supprimer complètement le CSS, tous les styles sont en ligne. Il est beaucoup plus rapide que prévu et présente de nombreux avantages pratiques intéressants, il évite également le coût de l'analyse CSS initiale du navigateur (qui est étonnamment coûteuse) et la correspondance des sélecteurs qui récupère la majeure partie des frais généraux. Je peux facilement atteindre 60 FPS stables et bien au-delà sur mon ordinateur portable sous-alimenté pour des hiérarchies même complexes (sans aucun élagage d'arbre).

J'imagine que la plupart de cela ne vous est pas vraiment utile, mais peut-être qu'il y a quelque chose d'intéressant là-dedans. Quoi qu'il en soit, mon principal reproche avec HTML + React est que les composants utilisateur React n'exposent aucune interface pour la mise en page/positionnement (et probablement dans une certaine mesure également les événements) sans recourir au CSS. Pour le dire simplement, si je crée un ButtonComponent puis que je l'utilise, par défaut, il ne peut pas être positionné ou intégré dans une mise en page sans ; en implémentant une logique spéciale à l'intérieur, en l'enveloppant dans un élément factice qui peut être positionné ou en exposant un style-prop qui est fusionné dans les styles utilisés pour l'élément racine ButtonComponent. Aucun de ceux-ci n'est parfait, et la fusion de styles tels quels est dangereuse car il est facile d'y mettre des styles que vous ne devriez pas. Essentiellement, le problème est qu'aux limites des composants, un sous-ensemble des propriétés disponibles devrait être public (positionnement/mise en page) et certains internes (style visuel).

Une autre chose que je fais est la séparation entre les composants et le contenu/les enfants. Par exemple, les composants DOM ne prennent pas une liste d'enfants, mais acceptent une instance de contenu. L'instance de contenu implémente la logique de réconciliation et le rendu des enfants, ce qui signifie que vous pouvez avoir différentes implémentations à des fins différentes. Les cas d'utilisation les plus évidents étant; principalement des hiérarchies statiques par rapport aux enfants générés dynamiquement. Ainsi, les hiérarchies statiques qui constituent la majorité peuvent être implémentées en utilisant une logique plus simple et plus rapide, tandis que les enfants générés dynamiquement peuvent avoir des stratégies configurables. Cela ouvre également la possibilité d'avoir des "composants de contenu" qui pourraient être utilisés pour gérer intelligemment, par exemple, les mises en page flexbox sans indirection inutile.

En rapport avec cela et quelque chose que je pense que React se trompe, ce sont les enfants, je ne suis pas encore arrivé à une conclusion ou à une solution spécifique. Mais je crois fermement qu'il y a un problème fondamental dans React en ce sens que vous ne pouvez pas déplacer les accessoires de la racine à un point arbitraire de la hiérarchie sans restituer chaque élément entre ces deux points et l'élagage est souvent problématique aussi. Les performances sont généralement "assez bonnes" et la complexité supplémentaire de la gestion de cela dans React peut ne pas valoir la peine d'être résolue. Mais dans mes expériences jusqu'à présent, j'ai été en mesure de réduire les coûts de mise à jour complète de la racine à de simples fractions avec de très petites quantités de code trivial, mais mon intuition dit que ce n'est pas très compatible avec la philosophie de React ou son modèle simpliste d'enfants.

Quelque chose qui n'est certainement pas pour vous, mais une grande caractéristique de ma bibliothèque est qu'elle ne fournit essentiellement qu'un "élément DOM de base" minimal à usage général. L'idée étant que vous pouvez trivialement étendre/remplacer et implémenter vos propres comportements spécifiques de bas niveau si vous développez un grand projet avec des exigences/circonstances spécifiques à très peu de frais et sans recourir à des "hacks", par exemple si vous êtes très fortement touché -orienté, veulent faire une gestion de style spéciale, etc. Cela signifie également que différentes versions sont compatibles et peuvent être exécutées côte à côte tant que l'ABI est le même (un changement devrait être extrêmement rare et très simple à corriger ). Cela signifie également que vous pouvez être assez opiniâtre dans l'interface de l'élément DOM sans avoir à être global et essayer de résoudre le problème de tout le monde.

Quoi qu'il en soit, peut-être que je ne fais que radoter et que je ne transmets probablement pas très bien la plupart des concepts, mais peut-être qu'il y a quelque chose d'intéressant pour vous de la part de quelqu'un qui est allé dans la direction opposée. La plupart d'entre elles ne vous concernent probablement pas simplement parce que vous visez la "simplicité", mais qui sait :)

De plus, avant que j'oublie, vous pourriez être intéressé par ma fonction objectKeyValueReconcile , spécifiquement optimisée pour être extrêmement rapide pour comparer les props prev/next pour des scénarios de type React. C'est pour moi un responsable de gains de performances assez importants dans le monde réel.

https://github.com/syranide/surgical/blob/master/packages/surgical/private/objectKeyValueReconcile.js

à mon humble avis, je laisserais tomber l'idée de "classe". JSX finira par mourir.

Que pensez-vous de l'ajout de la prise en charge des événements DOM/fenêtre non basés sur des éléments à React DOM ? Avec la suppression possible des événements synthétiques, je soupçonne qu'il y aurait encore une certaine forme de collecte/mise à jour/regroupement d'événements. Les événements de pression de touche, de redimensionnement et de défilement de fenêtre sont des scénarios courants qui viennent à l'esprit, mais être capable de prendre en charge la plupart/toute la liste dans https://developer.mozilla.org/en-US/docs/Web/Events serait être bénéfique derrière la même abstraction.

Cela se trouve également être discuté dans le plus ancien numéro ouvert #285 😄.

@gaearon

L'effet pratique de className -> class sera :

({ className }) => <div className={className} />

va devenir

({ ...rest }) => <div class={rest.class} />

Ce changement causera pas mal de douleur alors que les avantages sont entièrement théoriques . Nous avons vu d'autres communautés faire des choses similaires - par exemple, considérons que python3 a été publié pour la première fois il y a dix ans et nous nous disputons toujours à ce sujet. Une partie importante de la communauté n'a pas fait la transition et ne le fera jamais. Veuillez reconsidérer.

@kans

Ou ca:

props => <div class={props.class} />

C'est d'une complexité similaire à la fonction d'origine.

J'ai aimé className parce que class est un mot-clé dans js, mais ne pense pas que ce soit si grave de toute façon. Je préfère le style avec quelque chose comme glamour, donc ce n'est pas quelque chose qui m'affecte. J'ai peut-être utilisé className une douzaine de fois ces dernières années ?? Presque jamais.

Bien qu'une pensée qui m'est venue en faveur de class est que la plupart des gens qui utilisent réellement className utilisent css, et ils s'attendent au modèle html/css de class . L'objectif primordial de cet accessoire est vraiment de créer un lien avec le code CSS, n'est-ce pas, alors pourquoi ne pas simplement l'appeler classe comme un utilisateur html/css s'y attend ?

IMO en dehors du code du système de conception, le développement vraiment idiomatique de React n'utiliserait généralement pas beaucoup className ou class de toute façon. Lorsque j'ai besoin d'utiliser des classes pour CSS, il est principalement isolé de quelques petits composants d'interface utilisateur. Pratiquement tout ce qui est utilisé au niveau de la couche application est de niveau supérieur (comme, par exemple, <Columns verticalAlign="center"> ou <BodyText /> ).

Donc je suppose que je me demande si le fait de renommer de className à class rend plus facile pour le genre de personnes qui utilisent l'accessoire de toute façon (plus facile d'entrer dans le développement de React, de changer de contexte, de ne pas se fâcher , etc.), pourquoi ne pas simplement le renommer ?

Réduisez la taille du paquet s'il vous plaît.

Puisqu'il s'agit d'une grosse mise à jour, nous pourrions peut-être également corriger la dénomination du cycle de vie de React !

c'est-à-dire shouldComponentUpdate => shouldUpdate , etc. Cette dénomination est plus que stupide.

@AlexGalays

Puisqu'il s'agit d'une grosse mise à jour, nous pourrions peut-être également corriger la dénomination du cycle de vie de React !

c'est-à-dire shouldComponentUpdate => shouldUpdate, etc. Cette dénomination est plus que stupide.

Les noms de hook de cycle de vie plus longs sont moins ambigus lors de la recherche. Les noms plus courts sont trop génériques et dépendent du contexte dans lequel ils se trouvent, ils peuvent donc correspondre par coïncidence à autre chose qu'une grande base de code (correspondance faussement positive).

Les méthodes de cycle de vie font partie du noyau de React, et ce problème concerne uniquement react-dom.

@ljharb
Oups, en effet !

@sompylasar
Désolé, ce n'est tout simplement pas une bonne raison (jeu de mots, ReasonReact a corrigé les noms de méthodes :)). Nous ne préfixons pas non plus tous nos modules par leurs noms de packages et nous les trouvons très bien. Quoi qu'il en soit, je vais arrêter d'en parler puisque react-core est hors de portée dans ce numéro.

J'aimerais voir ces changements.
J'espère qu'ils seront implémentés avec l'interopérabilité des éléments personnalisés à l'esprit.

Je me demande s'il vaut la peine de déplacer certaines discussions vers des fils de discussion séparés dans le forum (https://discuss.reactjs.org) ? Étant donné que les problèmes GitHub ne sont pas traités comme des messages de forum, il est difficile de discuter de plusieurs choses différentes dans le même problème.

Le changé de className -> class me semble intéressant 😺

Regarder, projets React 2019

const {
  class: className, // YouKnowIamRight PepeHands
  someFancyProp,
  ...restProps
} = props

Je vois cela venir à coup sûr.

J'adore pouvoir copier-coller du HTML et ne pas avoir à modifier className , mais en même temps, je vois les problèmes que le mot-clé réservé class pourrait apporter.

À ce stade, je préférerais m'en tenir à className moins que vous n'ayez une forte préoccupation technique à ce sujet (pas de préférence personnelle)

Mais ce n'est que mon avis pragmatique.

Bien que je comprenne la friction supplémentaire de ne pas pouvoir détruire l'identifiant class , j'ai l'impression que trop de gens dans ce fil surestiment le nombre de fois qu'ils doivent recevoir le nom de la classe comme accessoire.

Passer className à un composant React (qui n'est pas seulement un élément DOM) signifie soit que vous créez des blocs de construction assez petits sans fournir de nouvelles abstractions, soit que ce composant expose certains de ses détails d'implémentation. Dans le premier cas (par exemple, composant <Button /> ), vous voudrez probablement suivre l'exemple de @gaearon et transmettre également le "reste" des accessoires à l'élément DOM. Dans le second cas, peut-être que la friction supplémentaire vous obligerait à éviter de faire la chose et à trouver une meilleure solution.

D'après mon humble expérience, j'ai dû copier coller HTML dans JSX (et remplacer class par className ) plus de fois que je ne me souviens avoir créé un composant qui reçoit className .

Répandre tous les accessoires dans un HTML est un anti-modèle. Si quelqu'un à l'avenir inclut un accessoire supplémentaire qui correspond à un attribut HTML, cela modifiera le comportement de manière inattendue. Si IE ajoute un nouvel attribut, vous êtes arrosé.

@philipwhiuk si vous ne diffusez que les accessoires que vous n'utilisez pas, il n'y aura pas de problèmes de comportement.

@j-f1

si vous ne diffusez que les accessoires que vous n'utilisez pas, il n'y aura pas de problèmes de comportement.

Pas vraiment. Si vous ajoutez une nouvelle option à votre API de composant, cette option cesse d'être transmise au nœud DOM sous-jacent. Quelqu'un peut dépendre de cet attribut exact défini sur l'élément, puis vous cassez cette personne. Répartir tous les accessoires inutilisés sur tout ce qui se trouve en dessous signifie que tout ajout à votre API de composant est un changement radical.

Au fait, j'ai utilisé un exemple aléatoire où vous déconstruisez la valeur de class mais ne vous coupez pas sur ce détail.

Beaucoup d'entre vous (oui, vous le faites) déconstruisent presque toutes les valeurs de props et state au lieu d'utiliser la notation par points pour des raisons autres que d'éviter de taper du texte supplémentaire.

C'est pourquoi je mets l'accent sur la situation, mais n'allez pas de côté et ne vous concentrez pas sur la diffusion d'accessoires ou sur tout autre sujet secondaire dont vous pourriez parler.

Si vous êtes un peu plus pragmatique, vous parleriez des implications techniques au lieu de vos préférences personnelles, mais je ne vois personne dire quoi que ce soit sur les implications techniques de className .

Une autre chose à laquelle vous devez faire attention est que vous obligez les contributeurs principaux à se concentrer sur quelque chose qui est une question de préférences personnelles (prouvez-moi le contraire, juste parce que je veux que vous y réfléchissiez de manière pragmatique)

Leur temps, leurs efforts et leur argent (de la part de l'entreprise) sont limités, alors mieux vaut que la communauté comprenne qu'il y a de meilleures choses sur lesquelles concentrer notre attention et si quelqu'un de l'équipe principale consacrera une heure à quelque chose que nous préférons utiliser dans la prochaine grande chose pour React, pas de code de refactorisation pour un tel changement.

Mais encore une fois, mon avis pragmatique.

En parlant de polyfills, je ne pense pas que react devrait essayer de détecter si l'utilisateur a spécifié de "bons" polyfills.
(par exemple hasBadMapPolyfill dans le code)
React ne devrait pas être tenu responsable de toutes les erreurs aléatoires que l'on peut commettre dans un projet de programmation.

@AlexGalays React s'appuie sur l'utilisation d'une implémentation Map avec une sémantique correcte. Si les utilisateurs utilisent un polyfill non conforme, leur application peut se casser de manière inattendue et déroutante, il est donc utile d'avertir à l'avance dans ce cas.

Cela n'est également fait que dans la version de développement, il n'y a donc pas de frais généraux pour cela en production.

J'adore ce React Fire et vous continuerez à travailler dessus car cela semble être une étape plus intéressante pour moderniser le ReactDOM.

Serait-il possible que React Fire ne relie pas les gestionnaires d'événements?

class Compo exntends Compoent {
 onClick() {
   ...
 }
  render() {
   <button onClick={this.onClick} >click me </button>
  }
}

Je ne pense pas que quiconque veuille réellement que le gestionnaire d'événements soit rebondi. Et dans les rares cas où vous le feriez, vous pourriez le lier manuellement

@cullophid

Serait-il possible que React Fire ne relie pas les gestionnaires d'événements?

Vous pouvez lier la méthode à la classe une fois en utilisant les liaisons automatiques de la fonction fléchée ou en liant la fonction dans votre constructeur. Si vous souhaitez enchaîner des paramètres uniques sur l'événement, vous pouvez chercher à mémoriser les gestionnaires d'événements ou à attacher des attributs DOM aux nœuds eux-mêmes et y accéder via event.currentTarget .

class Compo extends Compoent {
 onClick = () => {
   ...
 }
 render() {
   <button onClick={this.onClick}>click me</button>
 }
}

Un autre avantage de la simplification du système d'événements (pouvons-nous revenir aux événements DOM bruts sans aucune mise en commun comme le font TOUS les frameworks ? :) ) est qu'il est également plus facile de taper de manière statique.

Ça a l'air d'être un super plan ! Ce serait vraiment bien d'avoir le support d'IE 11 (même si cela signifie expédier nos propres polyfills, ce qui est tout à fait correct). En tant que personne qui travaille avec des clients gouvernementaux, quand ils cesseront d'utiliser IE 11 est une inconnue totale :(

@MatthewHerbst même bateau, nos clients utilisent IE 11 et nous en avons assez de trafic 😢

Je voulais juste intervenir pour dire que tout cela est super excitant. La seule chose que j'ai lu qui m'a inquiété c'est :

il est possible que nous n'essayions pas de lisser certaines des différences de navigateur existantes

En ce moment, j'aime savoir que le système d'événements de React "fonctionnera simplement" sur n'importe quel navigateur pris en charge par React. J'ai bien peur que ce changement signifie qu'il incombera à l'application de prendre en compte les problèmes liés à plusieurs navigateurs. Cela introduirait probablement beaucoup de bogues difficiles à tracer. ... du moins pour mes applications. :)

Quoi qu'il en soit, merci comme toujours pour la grande bibliothèque.

@kentcdodds avait mentionné l'intégration de JSX 2.0 comme une idée possible que je lisais dans la stratégie et je n'ai rien vu qui semblait lié à cela. Je me demandais si c'était juste en l'air ou quelque chose qui sera retardé pour l'avenir ?

Laissez l'IE mourir ! Ne supporte pas les navigateurs absolument obsolètes. Il n'y a aucune raison, même pour les entreprises restrictives, de ne pas passer à un navigateur à jour. Vous verrez cet IE11 dans vos statistiques jusqu'à ce que vous et le Web cessez de le prendre en charge.

Logiciel hérité @hbroer ?

@hbroer personne ne reste sur un ancien navigateur parce que ses sites fonctionnent toujours, ils le font parce qu'ils n'ont pas le choix ou ne savent pas comment mettre à jour. Briser un site pour ces utilisateurs est extrêmement hostile et ne les laisse pas avec un navigateur mis à jour, mais sans rien.

  • "ne sais pas comment mettre à jour" - pas notre problème, mais nous pouvons mettre dans les messages "installer un nouveau navigateur" avec une liste de navigateurs et peut-être avec un texte d'aide et le numéro de téléphone de la hotline Microsoft ^^
  • "n'ont pas le choix" - C'est vrai, mais l'organisation doit mettre à jour son environnement. Si leurs outils ne fonctionnent pas, ils le feront.

Je déteste coder pour le passé et je ne peux pas profiter des nouvelles technologies, car 90 % des codeurs prennent toujours en charge les navigateurs de merde des 15 % de consommateurs les plus pauvres vivant au siècle dernier. ^^ Je ne veux pas avoir ce "oh qu'est-ce qu'il y a avec ces nerds d'Internet Explorer 6, nous devons supporter ces 15%" encore pendant les 10 prochaines années.

btw M$ semble apporter Edge pour Windows 7 et 8 avec leur passage à webkit.

@hbroer tout est notre problème si cela impacte les utilisateurs. Ayez de l'empathie pour les autres humains.

(Séparément, M$ est une référence assez juvénile et très datée de la fin des années 90 que vous souhaiterez peut-être supprimer ; je serais heureux de supprimer cela si vous le faites)

Je vois, voici de nombreux fanboiz M$. :DI se soucie vraiment des humains, mais pas des organisations qui bloquent la progression de la technologie, ou des codeurs qui veulent supporter cette vieille merde pendant des années. Je n'ai aucun problème avec un paquet supplémentaire qui rend une bibliothèque "compatible avec les vieilles conneries". Mais une bibliothèque en 2019 devrait être codée avec la technologie >=2019 à l'esprit, et non avec la technologie <=2013. C'est déjà assez grave d'avoir à supporter ce (oh, faisons cela un peu autrement) le safari et la (vieille) merde de bord.

microgoutte

@hbroer, en fait, l'ancien navigateur Android et l'ancien safari posent plus de problèmes que n'importe quel navigateur Microsoft. il ne s'agit pas d'être un "fanboi" mais d'être professionnel, et utiliser le terme "M$" ne l'est pas.

Et non, ce n'est en aucun cas "mauvais" de soutenir l'ancienne technologie, c'est la chose morale et éthique à faire. Ce qui est mauvais, ce sont les sites Web qui "fonctionnent le mieux sous X", qu'il s'agisse de Netscape Navigator, d'IE 6 ou du dernier Chrome.

Je vois, voici de nombreux fanboiz M$.

@hbroer Je vois ici une personne avec des attaques généralisées ad hominem.

Mais une bibliothèque en 2019 devrait être codée avec la technologie >=2019 à l'esprit, et non avec la technologie <=2013.

Non, ça ne devrait pas.

Si vous preniez une seconde et examiniez les paramètres par défaut de la liste des navigateurs, vous seriez surpris. Au lieu de cela, vous recourez à des attaques ad hominem et à des insultes au niveau de la cafétéria de l'école.

Une fois que vous avez suffisamment d'utilisateurs, IE11 devient un groupe important de personnes qui accèdent à votre site Web. Lors d'un emploi précédent, près d'un million de personnes par mois accédaient à notre site Web à partir d'IE11.

browsers

Si vous voulez prendre en charge les vieilles conneries, ajoutez des remplissages poly. Aucune raison de ne pas coder pour le futur et le présent. La prise en charge de l'ancienne technologie rend les applications Web plus lourdes et plus lentes que nécessaire.

Ps je vois une personne qui ne peut pas lire le sarcasme et ne se soucie pas des smileys ^^

@hbroer Vous montrez que IE11 est le présent, nous sommes donc censés coder pour cela.

Et, encore une fois. Voir la valeur par défaut sur https://browserl.ist.

Ps je vois une personne qui ne peut pas lire le sarcasme et ne se soucie pas des smileys ^^

Ouais non. Il s'agit d'une tactique courante employée par les trolls et les intimidateurs des terrains de jeux. "Quoi?! Je ne t'ai pas insulté! C'était juste une blague!".

0,20% des habitants de la planète, même filtrés par "ceux qui utilisent internet", c'est 6,4 millions d'êtres humains. Les pourcentages n'ont aucune importance. Code pour les humains ; le passé et le futur, et la taille de votre forfait, n'ont pas d'importance.

Si vous souhaitez coder pour la taille du bundle humain, tout comme la compatibilité du navigateur, cela compte certainement. Les utilisateurs s'attendent non seulement à ce que les choses fonctionnent, mais elles doivent également être rapides à charger.

Maintenant, en 2019, j'utiliserai pour les nouveaux projets la grille CSS (qui n'a qu'un support expérimental sur IE11), et je transpilerai vers ES6 et je ne veux pas fournir de polyfills pour ce navigateur obsolète. Les utilisateurs d'IE11 reçoivent simplement un message : mettez à jour votre navigateur ou utilisez une alternative.

Il y a des gens qui ne veulent pas utiliser java script. Vous vous souciez d'eux? Vous ne voyez pas que les gars dans les statistiques. Et je ne suis pas non plus dans les statistiques, comme beaucoup d'autres personnes qui bloquent ces outils.

Je regarde chaque navigateur qui n'est pas obsolète. Je prends en charge edge, qui a moins d'utilisateurs que cette merde IE11, à cause de Windows 7 (qui prend en charge les fins de janvier 2020), et les gens modernes utilisent des navigateurs modernes. ^^

Personne ne vous empêche d'utiliser des polyfills et quelque chose comme un package de compatibilité. Mais le noyau doit être à jour et ne pas rester loin derrière uniquement à cause d'un morceau d'un ancien navigateur technologique M $.

Ce qui me manque dans de nombreux frameworks javascript, c'est LTS. C'est de ça qu'on peut parler. Si vous créez une page moderne avec des fonctionnalités du présent, il est agréable d'utiliser un cadre technologique à jour. Et si vous construisez une application Web pour des trucs b2b qui ont besoin du maximum de stabilité et de compatibilité, vous pouvez utiliser une version LTS. Ou utilisez le KO. Ensuite, vous pouvez prendre en charge les quelques 100 personnes qui utilisent encore un Windows XP non mis à jour avec IE6 ^^

La compatibilité est clairement répertoriée sous "compromis" dans le message d'origine, donc avoir une prise en charge parfaite des anciens navigateurs est déjà un objectif secondaire.

Ils nécessiteront plus de polyfills et d'intégration si vous avez besoin de les prendre en charge, mais ce serait votre choix de le faire. Vous pouvez également créer plusieurs bundles pour différentes cibles de navigateur et fournir le plus petit JS possible pour chaque visiteur afin que cela n'affecte pas l'ensemble de votre public.

Les progrès sur React Fire lui-même ne semblent pas affectés, il n'y a donc vraiment rien à gagner de ce débat. Passons à autre chose s'il vous plaît et revenons au sujet principal.

Serait-ce une bonne occasion de résoudre le #6410 ? Son impact semble similaire aux modifications proposées pour onChange / onInput .

Mise à jour du 5 juin 2019

Cela fait longtemps. Voici une petite mise à jour sur où nous en sommes.

Nous avons commencé à travailler sur Fire en décembre. Il y a des travaux en cours dans https://github.com/facebook/react/pull/14382 et d'autres fils. Cependant, alors que nous commencions à supprimer des parties du système d'événements que nous pensions inutiles ou obsolètes, nous avons découvert de nombreux cas extrêmes où il était très utile et empêchait les bogues, même dans les navigateurs modernes. Nous voulons toujours réduire le gonflement hérité, mais il n'est pas clair qu'être plus proche des événements DOM bruts soit la meilleure direction dans la pratique. Réduire le code de la bibliothèque uniquement pour le rajouter plusieurs fois dans le code de l'application n'est pas le meilleur compromis. Et il n'est même pas toujours possible de le réparer au niveau de l'application.

Séparément, en travaillant sur FB5 , nous avons réalisé que même en utilisant React, il existe aujourd'hui des difficultés importantes dans la mise en œuvre d'interfaces utilisateur qui fonctionnent et se sentent bien sur les souris et les appareils tactiles. Même les choses de base comme les boutons se sentent très différentes avec la souris et le toucher lorsque vous utilisez des événements comme onClick , et il devient encore plus difficile d'obtenir un comportement cohérent avec le survol, le focus, etc.

Ainsi, lorsque nous avons commencé à travailler sur Fire, nous avons pensé qu'un système d'événements personnalisés n'était peut-être pas nécessaire. Mais après l'avoir supprimé, nous avons réalisé que notre système d'événements est en fait notre plus grand levier pour résoudre cet ensemble de problèmes .

À la suite de cette enquête, nous avons temporairement suspendu le travail sur d'autres éléments faisant partie de React Fire et avons décidé de nous concentrer d'abord uniquement sur le système d'événements. Ce projet est devenu connu sous le nom de React Flare (https://github.com/facebook/react/issues/15257). C'est assez difficile en soi et affecte les autres éléments de cette liste, nous nous concentrons donc d'abord dessus de manière isolée.

L'objectif de React Flare est de faciliter la création d'interfaces utilisateur qui se sentent bien sur le bureau et le mobile, avec la souris et le toucher, et qui sont accessibles. Il comprend des API déclaratives pour gérer les interactions telles que Press, Hover et Focus. Contrairement au système d'événements React actuel, la conception Flare ne gonfle pas le bundle pour les événements que vous n'utilisez pas - et devrait permettre de réduire la quantité de code dans les bibliothèques d'interface utilisateur qui traitent des événements de souris et tactiles.

React Flare est encore une expérience, mais nous sommes assez confiants dans son orientation générale et prévoyons de le rendre finalement officiellement disponible en open source. (Pour l'instant, cela ne fonctionne que si vous construisez manuellement à partir de master, et il n'y a aucune garantie de semver car nous y travaillons activement.) Comme Fire, "Flare" n'est qu'un nom de code - au moment où nous l'expédierons, il aura nom correct, documentation, etc. Peut-être react/events ou quelque chose comme ça. Nous aimerions également proposer des événements équivalents dans React Native à terme.

Après avoir terminé la mise en œuvre initiale de React Flare, nous reviendrons à la liste React Fire et réévaluerons tous les autres points en utilisant ce que nous en avons appris. Il est toujours probable que si Flare prend en charge un ensemble d'événements "plus riche", nous pouvons simplifier la gestion des événements "de base" dans React DOM et supprimer un tas de polyfills. Merci à tous pour la discussion jusqu'à présent, et j'espère que cela vous sera utile.

Bon travail! Ainsi, le système d'événements est toujours nécessaire pour équilibrer les événements de souris et de toucher, mais il sera léger et indépendant de React.

"React Flare" fera-t-il partie du package React par défaut ou nécessitera-t-il une installation supplémentaire compte tenu de la quantité d'API avec laquelle il sera livré ?

Nous aimerions éviter que le code inutilisé ne soit regroupé. L'intention actuelle est donc que ce soit opt-in par API. Peut-être des points d'entrée séparés dans un seul paquet.

Ce système d'événements de souris et de toucher tirera-t-il parti de PointerEvent ? Je n'ai pas vu de mention de cette norme Web dans la mise à jour précédente, je voulais donc simplement la porter à votre attention.

Les événements de pointeur sont des événements DOM déclenchés pour un périphérique de pointage. Ils sont conçus pour créer un modèle d'événement DOM unique pour gérer les périphériques d'entrée de pointage tels qu'une souris, un stylo/stylet ou le toucher (comme un ou plusieurs doigts). Le pointeur est un périphérique indépendant du matériel qui peut cibler un ensemble spécifique de coordonnées d'écran. Le fait d'avoir un modèle d'événement unique pour les pointeurs peut simplifier la création de sites Web et d'applications et offrir une bonne expérience utilisateur, quel que soit le matériel de l'utilisateur.

Et voici un lien direct vers la compatibilité actuelle du navigateur .

@jonathantneal Oui, le nouveau système utilise fortement les événements de pointeur - avec des retours aux événements de souris/tactile lorsqu'il n'y a pas de prise en charge des événements de pointeur.

Je crains que https://github.com/facebook/react/issues/11347 n'ait pas été abordé dans ce numéro. Réagissez les ratés https://custom-elements-everywhere.com.

Veuillez prendre en compte la racine fantôme lors de la refonte du système d'événements - le simple fait de s'attacher à la racine de React ne résoudrait pas la plupart des problèmes aujourd'hui, mais uniquement de s'attacher à l'élément (https://github.com/facebook/react/issues/9242, https:// github.com/facebook/react/issues/15759, https://github.com/facebook/react/issues/13713, https://github.com/facebook/react/issues/11827)

Dans cette mise à jour : https://github.com/facebook/react/issues/13525#issuecomment -499196939 @gaearon mentionne :

Cependant, alors que nous commencions à supprimer des parties du système d'événements que nous pensions inutiles ou obsolètes, nous avons découvert de nombreux cas extrêmes où il était très utile et empêchait les bogues, même dans les navigateurs modernes.

J'étais curieux de savoir si une liste de ces cas extrêmes est documentée quelque part ?

@gaearon maintenant que Flare est sorti (SCNR), existe-t-il un plan mis à jour (concernant la mise à jour du 5 juin 2019 ) comment procéder ?

Et comme @trusktr , j'aimerais aussi que le #11347 soit adressé ici.

Les polyfills pourraient être divisés en un autre ensemble, en particulier celui qui n'est pas pertinent pour les principaux navigateurs à feuilles persistantes.

Salut à tous, ça fait un moment et nous avons essayé certaines de ces choses par intermittence.

Permettez-moi de faire le point sur chacun :

Nous voulons toujours le faire, mais nous avons décidé de "réserver" React 17 pour avoir un minimum de changements de rupture possibles afin qu'il puisse se concentrer sur l'élément suivant de cette liste. Ce changement attendra donc React 18.

  • Joignez les événements à la racine de React plutôt qu'au document (https://github.com/facebook/react/issues/2043). Attacher des gestionnaires d'événements au document devient un problème lors de l'intégration d'applications React dans des systèmes plus importants. L'éditeur Atom a été l'un des premiers cas qui s'est heurté à cela. Tout grand site Web développe également éventuellement des cas périphériques très complexes liés à stopPropagation interagissant avec du code non-React ou à travers des racines React (https://github.com/facebook/react/issues/8693, https://github .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). Nous voudrons également attacher des événements avec impatience à chaque racine afin de pouvoir effectuer moins de vérifications d'exécution lors des mises à jour.

Nous le faisons dans React 17. Cela s'est avéré être un énorme travail, mais heureusement, c'est terminé.

  • Migrez de onChange vers onInput et ne le polyfillez pas pour les composants non contrôlés (https://github.com/facebook/react/issues/9657). Voir le problème lié pour un plan détaillé. Il est déroutant que React utilise un nom d'événement différent pour ce qu'on appelle l'événement input dans le DOM. Bien que nous évitions généralement de faire de gros changements comme celui-ci sans avantage significatif, dans ce cas, nous voulons également modifier le comportement pour supprimer une certaine complexité qui n'est nécessaire que pour les cas extrêmes comme la mutation des entrées contrôlées. Il est donc logique de faire ces deux changements ensemble et d'utiliser cela comme une opportunité pour que onInput et onChange fonctionnent exactement comme les événements DOM fonctionnent pour les composants non contrôlés.

Nous y reviendrons probablement, mais on ne sait pas combien de désabonnement vaut la peine d'être fait ici. Donc c'est encore à déterminer.

  • Simplifiez considérablement le système d'événements (https://github.com/facebook/react/issues/4751). Le système d'événements actuel a à peine changé depuis sa mise en œuvre initiale en 2013. Il est réutilisé dans React DOM et React Native, il est donc inutilement abstrait. La plupart des polyfills qu'il fournit ne sont pas nécessaires pour les navigateurs modernes, et certains d'entre eux créent plus de problèmes qu'ils n'en résolvent. Il représente également une partie importante de la taille du bundle React DOM. Nous n'avons pas de plan très précis ici, mais nous allons probablement bifurquer complètement le système d'événements, puis voir à quel point nous pouvons le rendre minimal si nous nous en tenons plus près de ce que le DOM nous donne. Il est plausible que nous nous débarrassions complètement des événements synthétiques. Nous devrions arrêter les événements bouillonnants comme les événements médiatiques qui ne bouillonnent pas dans le DOM et n'ont pas de bonne raison de bouillonner. Nous souhaitons conserver certaines fonctionnalités spécifiques à React, telles que le bouillonnement à travers les portails, mais nous essaierons de le faire par des moyens plus simples (par exemple, redistribuer l'événement). Les événements passifs en feront probablement partie.

Nous avons essayé cela au début de 2019, et un système d'événements vraiment minimal n'a pas très bien fonctionné lors de nos tests internes. Il y avait pas mal de normalisation entre navigateurs que React fait qui est toujours utile pour les personnes avec des navigateurs plus anciens, ou dans des domaines plus spécialisés comme les éditeurs de saisie de texte enrichi utilisant contentEditable . Cela dit, dans le cadre de notre travail sur l'attachement des événements aux racines, nous avons supprimé beaucoup d'abstraction du système d'événements afin qu'il soit plus facile à comprendre et à améliorer à l'avenir. Dans le cadre de React 17, nous supprimons le "regroupement d'événements" qui a causé beaucoup de confusion, et nous ne diffusons plus l'événement onScroll . Nous suivrons probablement en arrêtant le bouillonnement des événements médiatiques dans React 18, rapprochant le comportement de React de celui du navigateur. Nous avons économisé quelques octets avec le nouveau système d'événements, mais ils ont été pris par de nouvelles fonctionnalités sur lesquelles nous travaillons, donc cela ne conduira pas à une diminution globale de la taille du bundle.

  • classNameclass (https://github.com/facebook/react/issues/4331, voir aussi https://github.com/facebook/react/issues/13525#issuecomment- 417818906 ci-dessous). Cela a été proposé un nombre incalculable de fois. Nous autorisons déjà le passage class au nœud DOM dans React 16. La confusion que cela crée ne vaut pas les limitations de syntaxe contre lesquelles il essaie de se protéger. Nous ne ferions pas ce changement par lui-même, mais combiné avec tout ce qui précède, il a du sens. Notez que nous ne pouvons pas autoriser les deux sans avertissement, car cela rend la gestion très difficile pour un écosystème de composants. Chaque composant devrait apprendre à gérer les deux correctement, et il y a un risque qu'ils entrent en conflit. Étant donné que de nombreux composants traitent className (par exemple en y ajoutant), il est trop sujet aux erreurs.

C'était la partie la plus controversée de la proposition. Depuis lors, nous avons publié des crochets, qui encouragent l'écriture de composants fonctionnels. Dans les composants de fonction, nous suggérons généralement d'utiliser la déstructuration pour les accessoires, mais vous ne pouvez pas écrire { class, ... } car ce serait une erreur de syntaxe. Donc, dans l'ensemble, il n'est pas clair que cela soit suffisamment ergonomique pour être suivi. Je pense qu'il est plausible que nous réexaminions cela à l'avenir, ou au moins que class ne prévienne pas et laisse les gens faire ce qu'ils veulent. Mais pour l'instant, nous allons mettre cette idée de côté.

Salut, c'est un super article !
Je voulais juste savoir s'il y avait un plan en cours pour réduire la taille de la prod React-DOM ? Pour les applications mobiles, il s'agit toujours d'une surcharge car le navigateur analysera plus de 100 Ko de React-DOM JS, puis d'autres modules. Puis JS spécifique à l'application.
Pour les pages riches en contenu, cela provoque un blocage plus important et un TTI plus important.

Une idée quand pouvons-nous voir de tels changements?

@morevolk-latei Dans vos mesures, combien de temps est passé à analyser 100 Ko de ReactDOM ?

Cette page vous a été utile?
0 / 5 - 0 notes