React: autoFocus ne fonctionne pas avec SSR dans React 16

Créé le 9 oct. 2017  ·  12Commentaires  ·  Source: facebook/react

<input autoFocus /> fonctionne sur le client mais pas lorsqu'il est hydraté.

C'est parce que cela était implémenté dans JS en tant que cas spécial, mais hydrateInstance ne provoque pas la planification d'un effet de validation pouvant appeler .focus() comme le fait finalizeChildren .

La question ici est de savoir si nous nous soucions même de l'implémenter dans JS ou devrions-nous simplement émettre l'attribut autofocus dans SSR et laisser le navigateur s'en occuper.

Server Rendering Bug

Commentaire le plus utile

La raison initiale de ne pas émettre l'attribut autofocus était que les implémentations du navigateur étaient largement incohérentes dans la façon dont elles le traitaient (certaines ne le prennent pas en charge, d'autres se concentrent uniquement sur le chargement de la page, etc.). Quel IMHO signifie que quiconque est sérieux au sujet de l'autofocus devait de toute façon l'appliquer manuellement via JS. Cependant, je me souviens vaguement qu'il existe maintenant des navigateurs mobiles qui n'écoutent pas vraiment la mise au point JS, mais qui honorent dans une certaine mesure la mise au point automatique.

C'est un gâchis, mais il y a un certain mérite à simplement émettre l'attribut, et si vous en êtes convaincu, vous vous concentrez manuellement. On vous donne tous les outils.

Tous les 12 commentaires

Je pense que nous devrions émettre l'autofocus comme attribut.

Il semble que le principal inconvénient est que autofocus n'est pas pris en charge dans IE9, iOS Safari et le navigateur Android . Y a-t-il d'autres inconvénients qui me manquent? À quel point serait-il difficile / mécanique d'ajouter l'autofocus via JS?

Si nous le faisons toujours en JS, c'est assez facile, mais cela semble assez mauvais pour la sémantique. Le chargement de tous les scripts peut prendre un certain temps avant de se concentrer. L'utilisateur peut se concentrer sur d'autres choses entre-temps, puis soudainement il devient concentré. Étant donné qu'avec la fibre, nous pouvons nous réhydrater de manière asynchrone et nous pourrions également vouloir faire une hydratation partielle, cela pourrait rendre la situation encore pire qu'elle ne l'est déjà.

Nous pouvons faire les deux, mais vous avez des artefacts étranges sur lesquels il peut se concentrer, vous vous éteignez et ensuite il se concentre à nouveau.

Nous ne pourrions potentiellement le faire dans JS que si le normal échoue, mais je ne sais pas comment le détecter et cela pourrait ajouter beaucoup de code.

Je ne sais pas quel est le bon compromis ici étant donné le problème de prise en charge du navigateur.

Le chargement de tous les scripts peut prendre un certain temps avant de se concentrer.

Je pense que c'est un cas très fort pour émettre un attribut. Il semble que nous ne pouvons pas garantir l'exactitude, même si nous vérifions document.activeElement , l'utilisateur peut déjà être dans un flux ou avoir fait défiler la page. Nous ne voulons pas que la page saute ou que quelqu'un commence à taper dans une autre zone de saisie au milieu d'un coup de touche.

Désolé si une partie de cela est une répétition, mais ce serait l'argument que je ferais si quelqu'un posait un problème à ce sujet.

L'émission d'attributs semble être la bonne voie à suivre. Si je veux que l'autofocus fonctionne sur les navigateurs qui ne le prennent pas en charge, il me semble plus judicieux d'ajouter un script à la fin du corps:

    <script>!function(el){el&&el.focus()}(document.querySelector('[autofocus]'))</script>

Ce qui, je suppose, ne pose des problèmes que si la page HTML est très grande. Je suppose que cela pourrait également vérifier activeElement (si aucun ou body, puis se concentrer), mais cela pourrait être excessif.

La raison initiale de ne pas émettre l'attribut autofocus était que les implémentations du navigateur étaient largement incohérentes dans la façon dont elles le traitaient (certaines ne le prennent pas en charge, d'autres se concentrent uniquement sur le chargement de la page, etc.). Quel IMHO signifie que quiconque est sérieux au sujet de l'autofocus devait de toute façon l'appliquer manuellement via JS. Cependant, je me souviens vaguement qu'il existe maintenant des navigateurs mobiles qui n'écoutent pas vraiment la mise au point JS, mais qui honorent dans une certaine mesure la mise au point automatique.

C'est un gâchis, mais il y a un certain mérite à simplement émettre l'attribut, et si vous en êtes convaincu, vous vous concentrez manuellement. On vous donne tous les outils.

J'ai discuté avec @trueadm à ce sujet et je pense que cela semble être une voie plausible à suivre:

Réagir 16

  • Émettez-le en HTML SSR.
  • Assurez-vous de ne pas appeler JS polyfill pour les éléments hydratés.
  • Continuez à le mettre sur liste noire sur les éléments créés par le client et utilisez JS polyfill pour ceux-ci.

Réagir 17

  • Retirez complètement le polyfill JS.
  • Avertir s'il y a plus d'un élément autoFocus ajouté lors d'un commit (car c'est là que se produisent les incohérences du navigateur).

Est-ce que ça a du sens?

Avertir s'il y a plus d'un élément autoFocus ajouté lors d'une validation (car c'est là que se produisent les incohérences du navigateur).

Les navigateurs, du moins il n'y a pas si longtemps, sont également incohérents dans leur interprétation de l'attribut autoFocus. Je sais que par exemple, FF ne l'honorerait que sur pageload et ignorerait totalement ceux qui ont été insérés dynamiquement. Mais je ne l'ai pas étudié depuis longtemps maintenant.

Pourtant, je pense que l'approche est correcte.

Après quelques recherches de base, il semble que la plupart des navigateurs modernes, à l'exception de Safari, ne respectent pas du tout autoFocus après le chargement de la page.

Cela avait probablement du sens pour les documents HTML, mais dans les applications, je m'attendrais autoFocus ce que

Nous devrions donc probablement garder le polyfill.

Cela devient plus étrange.

Chrome respecte les éléments ajoutés dynamiquement avec autoFocus s'il n'y en a pas eu auparavant. Même en créant une entrée avec autoFocus , en l'ajoutant au document et en la supprimant lors de la prochaine coche, il suffit de désactiver la mise au point automatique de tous les éléments ajoutés à l'avenir dans Chrome.

Firefox ne se soucie tout simplement pas des éléments ajoutés dynamiquement avec autoFocus du tout.

Et Safari les respecte toujours.

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