React: autoFocus no funciona con SSR en React 16

Creado en 9 oct. 2017  ·  12Comentarios  ·  Fuente: facebook/react

<input autoFocus /> funciona en el cliente pero no cuando está hidratado.

Esto se debe a que esto solía implementarse en JS como un caso especial, pero hydrateInstance no causa que se programe un efecto de confirmación que pueda llamar a .focus() como lo hace finalizeChildren .

La pregunta aquí es, ¿deberíamos molestarnos en implementar esto en JS más o deberíamos simplemente emitir el atributo autofocus en SSR y dejar que el navegador se encargue de ello?

Server Rendering Bug

Comentario más útil

La razón inicial para no emitir el atributo de enfoque automático fue que las implementaciones del navegador eran muy inconsistentes en la forma en que lo trataban (algunas no lo admiten, otras solo se centran en la carga de la página, etc.). Lo que en mi humilde opinión significa que cualquiera que se tome en serio el enfoque automático tuvo que aplicarlo manualmente a través de JS de todos modos. Sin embargo, recuerdo vagamente que ahora hay navegadores móviles que realmente no escuchan el enfoque JS, pero sí respetan el enfoque automático hasta cierto punto.

Es un desastre, pero hay algo de mérito en simplemente emitir el atributo, y si te sientes muy bien, entonces te enfocas manualmente. Te dan todas las herramientas.

Todos 12 comentarios

Creo que deberíamos emitir el enfoque automático como atributo.

Parece que el inconveniente clave es que autofocus no es compatible con IE9, iOS Safari y el navegador Android . ¿Hay otros inconvenientes que me falten? ¿Qué tan difícil / mecánico sería agregar el enfoque automático a través de JS?

Si siempre lo hacemos en JS, es bastante fácil, pero parece bastante malo para la semántica. Todos los scripts pueden tardar un tiempo en cargarse antes de que realmente se concentre. El usuario puede enfocar otras cosas mientras tanto y luego de repente se vuelve enfocado. Dado que con la fibra podemos rehidratarnos de forma asincrónica y es posible que también queramos hacer una hidratación parcial, esto podría empeorarlo aún más de lo que ya es.

Podemos hacer ambas cosas, pero luego tienes artefactos extraños donde puede enfocarse, apagas y luego se enfoca nuevamente.

Potencialmente, solo podríamos hacerlo en JS si falla el normal, pero no estamos seguros de cómo detectarlo y eso podría agregar mucho código.

No estoy seguro de cuál es la compensación correcta aquí dado el problema de soporte del navegador.

Todos los scripts pueden tardar un tiempo en cargarse antes de que realmente se concentre.

Creo que este es un caso muy sólido para emitir un atributo. Parece que no podemos garantizar la exactitud, incluso si marcamos document.activeElement , es posible que el usuario ya esté en un flujo o se haya desplazado hacia abajo en la página. No queremos que la página salte hacia arriba o que alguien comience a escribir en otro cuadro de entrada a la mitad de la pulsación de una tecla.

Lo siento si algo de eso es un refrito, pero ese sería el argumento que haría si alguien presentara un problema al respecto.

Emitir atributo parece el camino correcto a seguir. Si quiero que el enfoque automático funcione en navegadores que no lo admiten, parece más sensato agregar un script al final del cuerpo:

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

Lo que supongo que solo causa problemas si la página HTML es muy grande. Supongo que también podría verificar activeElement (si no hay ninguno o el cuerpo se enfoca) pero eso podría ser excesivo.

La razón inicial para no emitir el atributo de enfoque automático fue que las implementaciones del navegador eran muy inconsistentes en la forma en que lo trataban (algunas no lo admiten, otras solo se centran en la carga de la página, etc.). Lo que en mi humilde opinión significa que cualquiera que se tome en serio el enfoque automático tuvo que aplicarlo manualmente a través de JS de todos modos. Sin embargo, recuerdo vagamente que ahora hay navegadores móviles que realmente no escuchan el enfoque JS, pero sí respetan el enfoque automático hasta cierto punto.

Es un desastre, pero hay algo de mérito en simplemente emitir el atributo, y si te sientes muy bien, entonces te enfocas manualmente. Te dan todas las herramientas.

Charlé con

Reaccionar 16

  • Emitirlo en SSR HTML.
  • Asegúrese de no llamar a JS polyfill para elementos hidratados.
  • Siga incluyéndolo en la lista negra de los elementos creados por el cliente y use JS polyfill para ellos.

Reaccionar 17

  • Elimine JS polyfill por completo.
  • Advertir si hay más de un elemento autoFocus agregado durante una confirmación (ya que aquí es donde ocurren las inconsistencias del navegador).

¿Esto tiene sentido?

Advertir si hay más de un elemento de autoFocus agregado durante una confirmación (ya que aquí es donde ocurren las inconsistencias del navegador).

Los navegadores, al menos no hace mucho, también son inconsistentes en la forma en que interpretan el atributo de enfoque automático. Sé que, por ejemplo, FF solo lo honraría en la carga de la página e ignoraría por completo cualquiera que se insertara dinámicamente. Pero no lo he examinado en mucho tiempo.

Aún así, creo que el enfoque es correcto.

Después de una investigación básica, parece que la mayoría de los navegadores modernos, excepto Safari, no respetan autoFocus después de cargar la página en absoluto.

Probablemente tenía sentido para los documentos HTML, pero en las aplicaciones esperaría que se respetara autoFocus por los elementos insertados dinámicamente, ya que son básicamente "transiciones de página" tanto como la primera carga de página en los SPA.

Así que probablemente deberíamos mantener el polyfill.

Se vuelve más extraño.

Chrome respeta los elementos agregados dinámicamente con autoFocus si no ha habido uno antes. Incluso crear una entrada con autoFocus , agregarla al documento y eliminarla en el siguiente tick es suficiente para deshabilitar el enfoque automático de cualquier elemento agregado en el futuro en Chrome.

A Firefox simplemente no le importan los elementos agregados dinámicamente con autoFocus en absoluto.

Y Safari siempre los respeta.

¿Fue útil esta página
0 / 5 - 0 calificaciones