React: React Fire: Modernización de React DOM

Creado en 31 ago. 2018  ·  227Comentarios  ·  Fuente: facebook/react


Para conocer el estado más reciente, vea una actualización del 5 de junio de 2019: https://github.com/facebook/react/issues/13525#issuecomment -499196939


Este año, el equipo de React se ha centrado principalmente en mejoras fundamentales para React .

A medida que este trabajo se acerca a su finalización, comenzamos a pensar en cómo deberían ser los próximos lanzamientos importantes de React DOM. Hay bastantes problemas conocidos , y algunos de ellos son difíciles o imposibles de solucionar sin grandes cambios internos.

Queremos deshacer los errores del pasado que causaron innumerables correcciones de seguimiento y crearon mucha deuda técnica. También queremos eliminar parte de la abstracción en el sistema de eventos que prácticamente no se ha tocado desde los primeros días de React, y es una fuente de mucha complejidad y tamaño de paquete.

Llamamos a este esfuerzo "Reaccionar fuego".

🔥 Reaccionar Fuego

React Fire es un esfuerzo por modernizar React DOM. Nuestro objetivo es hacer que React esté mejor alineado con la forma en que funciona el DOM, revisar algunas decisiones pasadas controvertidas que generaron problemas y hacer que React sea más pequeño y más rápido.

Queremos enviar este conjunto de cambios en un futuro lanzamiento importante de React porque, lamentablemente, algunos de ellos se romperán. Sin embargo, creemos que valen la pena. Y tenemos más de 50 mil componentes en Facebook para mantenernos honestos sobre nuestra estrategia de migración. No podemos darnos el lujo de reescribir el código del producto, excepto algunas correcciones específicas o modificaciones de código automatizadas.

Estrategia

Hay algunas cosas diferentes que conforman nuestro plan actual. Podríamos agregar o eliminar algo, pero aquí está el pensamiento hasta ahora:

  • Deja de reflejar los valores de entrada en el atributo value (https://github.com/facebook/react/issues/11896). Esto se agregó originalmente en React 15.2.0 a través de https://github.com/facebook/react/pull/6406. Se solicitó con mucha frecuencia porque el modelo conceptual del DOM de las personas es que el value que ven en el inspector del DOM debe coincidir con el atributo JSX value . Pero no es así como funciona el DOM. Cuando escribe en un campo, el navegador no actualiza el atributo value . React tampoco debería hacerlo. Resultó que este cambio, aunque probablemente útil para algunos códigos que dependen de los selectores de CSS, provocó una cascada de errores, algunos de los cuales aún no se han solucionado hasta el día de hoy. Algunas de las consecuencias de este cambio incluyen: 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 . En este punto, claramente no vale la pena seguir luchando contra el navegador, y deberíamos revertirlo. La parte positiva de este viaje es que, gracias al trabajo incansable de nuestros colaboradores de DOM ( @nhunzaker , @aweary , @jquense y @philipp-spiess), ahora tenemos dispositivos de prueba de DOM detallados que nos ayudarán a evitar regresiones.

  • Adjunte eventos en la raíz de React en lugar del documento (https://github.com/facebook/react/issues/2043). Adjuntar controladores de eventos al documento se convierte en un problema al integrar aplicaciones React en sistemas más grandes. El editor Atom fue uno de los primeros casos que se topó con esto. Cualquier sitio web grande eventualmente desarrolla casos extremos muy complejos relacionados con stopPropagation que interactúan con código que no es de React o a través de raíces de React (https://github.com/facebook/react/issues/8693, https://github .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). También querremos adjuntar eventos con entusiasmo a cada raíz para que podamos hacer menos comprobaciones de tiempo de ejecución durante las actualizaciones.

  • Migre de onChange a onInput y no lo rellene para componentes no controlados (https://github.com/facebook/react/issues/9657). Consulte el problema vinculado para obtener un plan detallado. Ha sido confuso que React use un nombre de evento diferente para lo que se conoce como evento input en el DOM. Si bien generalmente evitamos hacer grandes cambios como este sin un beneficio significativo, en este caso también queremos cambiar el comportamiento para eliminar cierta complejidad que solo es necesaria para casos extremos como la mutación de entradas controladas. Por lo tanto, tiene sentido hacer estos dos cambios juntos y usarlos como una oportunidad para hacer que onInput y onChange funcionen exactamente como lo hacen los eventos DOM para los componentes no controlados.

  • Simplifique drásticamente el sistema de eventos (https://github.com/facebook/react/issues/4751). El sistema de eventos actual apenas ha cambiado desde su implementación inicial en 2013. Se reutiliza en React DOM y React Native, por lo que es innecesariamente abstracto. Muchos de los polyfills que proporciona son innecesarios para los navegadores modernos y algunos de ellos crean más problemas de los que resuelven. También representa una parte significativa del tamaño del paquete React DOM. No tenemos un plan muy específico aquí, pero probablemente bifurcaremos el sistema de eventos por completo y luego veremos qué tan mínimo podemos hacerlo si nos atenemos más a lo que nos da el DOM. Es plausible que nos deshagamos de los eventos sintéticos por completo. Deberíamos dejar de burbujear eventos como eventos de medios que no burbujean en el DOM y no tienen una buena razón para burbujear. Queremos conservar algunas capacidades específicas de React, como burbujear a través de portales, pero intentaremos hacerlo por medios más simples (p. ej., reenviar el evento). Es probable que los eventos pasivos sean parte de esto.

  • classNameclass (https://github.com/facebook/react/issues/4331, consulte también https://github.com/facebook/react/issues/13525#issuecomment- 417818906 a continuación). Esto ha sido propuesto innumerables veces. Ya estamos permitiendo pasar class al nodo DOM en React 16. La confusión que esto crea no compensa las limitaciones de sintaxis contra las que intenta protegerse. No haríamos este cambio por sí solo, pero combinado con todo lo anterior tiene sentido. Tenga en cuenta que no podemos permitir ambos sin advertencias porque esto hace que sea muy difícil de manejar para un ecosistema de componentes. Cada componente necesitaría aprender a manejar ambos correctamente, y existe el riesgo de que entren en conflicto. Dado que muchos componentes procesan className (por ejemplo, al agregarlo), es demasiado propenso a errores.

compensaciones

  • No podemos hacer algunos de estos cambios si nuestro objetivo es seguir exponiendo las API privadas actuales del sistema de eventos React para proyectos como React Native Web. Sin embargo, React Native Web necesitará una estrategia diferente independientemente porque React Fabric probablemente moverá más del sistema de respuesta al lado nativo.

  • Es posible que debamos eliminar la compatibilidad con algunos navegadores antiguos y/o requerir más polyfills independientes para ellos. Todavía nos preocupamos por admitir IE11, pero es posible que no intentemos suavizar algunas de las diferencias existentes en el navegador, que es la postura adoptada por muchas bibliotecas de interfaz de usuario modernas.

Plan de despliegue

En esta etapa, el proyecto es muy exploratorio. No sabemos con certeza si todo lo anterior funcionará. Debido a que los cambios son significativos, tendremos que probarlos en Facebook y probarlos de manera gradual. Esto significa que presentaremos un indicador de función, bifurcaremos parte del código y lo mantendremos habilitado en Facebook para un pequeño grupo de personas. Las versiones de código abierto 16.x mantendrán el comportamiento anterior, pero en el maestro podrá ejecutarlo con el indicador de función activado.

Planeo trabajar en el proyecto yo mismo en su mayor parte, pero agradecería mucho más discusiones y contribuciones de @nhunzaker , @aweary , @jquense y @philipp-spiess, quienes han sido colaboradores estelares y han dirigido en gran medida React DOM mientras Estábamos trabajando en Fiber. Si hay algún área que te interese especialmente, házmelo saber y lo resolveremos.

Es probable que haya cosas que me perdí en este plan. Estoy muy abierto a recibir comentarios y espero que este artículo sea útil.

DOM React Core Team Big Picture

Comentario más útil

Me encantan todos estos puntos, excepto el cambio className . Parece francamente contradictorio con el objetivo que persiguen los otros puntos (alinearse con la API DOM). React se une a las propiedades DOM, no a los atributos HTML (esto es incluso articulado en el primer punto). La propiedad del Elemento DOM se llama className , no class . Entonces, ¿por qué se llamaría class en React?

Todos 227 comentarios

Me encanta esto. Reducir el tamaño del paquete y el accesorio de "clase" son cambios que serán muy bienvenidos.

¡Buen trabajo!

🙂

¡Atención a los autores de la biblioteca de formularios! 🤣

¡Genial!

className → la clase es fantástica

¿Qué pasa con todos los demás? Parece extraño que todavía esté haciendo clipPath , htmlFor , tabIndex , etc.

La adopción class es un gran avance para hacer que la biblioteca sea más amigable para los principiantes. Felicidades.

esto es genial Tengo mucha curiosidad por saber cómo funcionará el cambio a class con accesorios.

¿Parece que ({ class }) => <div class={class} /> presentaría inicialmente un problema de palabra clave reservada?

Esta es una noticia fantástica, gracias @gaearon!

Me encantan todos estos puntos, excepto el cambio className . Parece francamente contradictorio con el objetivo que persiguen los otros puntos (alinearse con la API DOM). React se une a las propiedades DOM, no a los atributos HTML (esto es incluso articulado en el primer punto). La propiedad del Elemento DOM se llama className , no class . Entonces, ¿por qué se llamaría class en React?

¡Fantástico! ¿Tiene un objetivo para la reducción del tamaño del paquete?

👏

¿Qué pasa con todos los demás? Parece extraño seguir haciendo clipPath, htmlFor, tabIndex, etc.

Estoy abierto a la discusión, pero diría que estos cambios no valen la pena (excepto for tal vez).

Creo que una reescritura del sistema de eventos es el aspecto más interesante de esto. Existe una gran oportunidad para reducir el tamaño del paquete y facilitar las contribuciones de la comunidad.

¡Vamos a hacerlo!

Me pregunto si valdría la pena trabajar también en el lanzamiento de JSX 2.0 al mismo tiempo. La gente necesitará volver a aprender un puñado de cosas de todos modos. ¿Quizás es mejor tener que volver a aprender un montón de una vez en lugar de algunas cosas dos veces en un período de tiempo? Sólo un pensamiento que se me ocurrió mientras leía esto.

Me encantan todos estos puntos, excepto el cambio className. Parece francamente contradictorio con el objetivo que persiguen los otros puntos (alinearse con la API DOM). React se une a las propiedades DOM, no a los atributos HTML (esto es incluso articulado en el primer punto).

Y, sin embargo, si pasamos un par clave/valor desconocido, se tratará como un atributo desde React 16. Por lo tanto, ya somos inconsistentes. Además, mi comentario se refería a que los usuarios estaban equivocados al esperar que React estableciera el atributo value . Si React API usa un nombre de atributo o un nombre de propiedad en su API es completamente ortogonal.

He defendido tu versión de este argumento durante años, pero ahora creo que esto es una fricción que simplemente no vale la pena. No ganas nada con eso. Permitir que las personas usen class no tiene efectos negativos, excepto que no funciona con la desestructuración y el costo de la migración. Todos se quejan cuando aprenden React. Creo que hacer lo que la gente espera en este caso es más importante que ser pedante. Y dado que estamos cambiando otras cosas del DOM de todos modos, agréguemoslo por lotes.

Mientras React Fire arda rápido.... 👍

Todos estos cambios son fantásticos. Estoy muy entusiasmado con esto y sus implicaciones para react-testing-library . En particular, los eventos están vinculados a la raíz de reacción (¿o tal vez incluso eliminar la delegación de eventos por completo, ya que puede que ya no sea necesario en entornos modernos?), Quitar/reescribir potencialmente eventos sintéticos y onChange -> onInput mejorará seriamente la implementación de react-testing-library y la experiencia en el uso de la herramienta.

Me encantaría proporcionar comentarios sobre esto a medida que se implementa.

tal vez incluso elimine la delegación de eventos por completo, ya que puede que ya no sea necesario en entornos modernos

Consideramos esto, pero creemos que podría ser una simplificación excesiva. La delegación de eventos nos permite evitar configurar un montón de oyentes para cada nodo en el renderizado inicial. Y cambiándolos en las actualizaciones. Esos aspectos no deben ser ignorados. Sin embargo, es probable que se realicen más evaluaciones comparativas allí.

@tannerlinsley ({ class: className }) => <div class={className} /> desafortunadamente esto eliminará la notación abreviada de objetos jsx 2.0 ( <div class /> ), pero que así sea...

Sería genial, genial si class finalmente pudiera tomar objetos y arreglos junto a cadenas.

¿Tiene un objetivo para la reducción del tamaño del paquete?

Sería bueno eliminar un tercio de React DOM. Ya veremos. Es difícil decirlo temprano, pero haremos nuestro mejor esfuerzo.

Guau, esta es una enumeración de casi todas las decisiones de diseño que menciono cuando la gente me pregunta sobre las desventajas de React.

Me encanta la dirección en la que va esto.

¿Cuál sería la ruta de actualización para las bibliotecas que usan className y desean admitir varias versiones de React?

@gaearon Tal vez no sea gran cosa, hoy es bueno decir "los accesorios son propiedades DOM, no atributos HTML", ahora será "excepto className, ese es el nombre HTML". También me gustaría poder copiar/pegar SVG sin 10 minutos de jugar con los atributos para que coincidan con los de React.

¿Qué pasa con htmlFor ?

Parece que la transición className -> class tendrá que hacerse con mucho cuidado, probablemente durante un período de tiempo prolongado. Va a causar muchos problemas para el ecosistema, ya que prácticamente todos los componentes deberán cambiarse, incluso los más triviales. Esto está bien si "posees" el código y hay un codemod, pero cuando dependes de bibliotecas de terceros, estás en gran medida a merced de los mantenedores.

El resto de los cambios parecen de riesgo relativamente bajo desde el punto de vista del ecosistema, pero deshacerse de className realmente causará mucho dolor. Parece que debería ser posible dividir eso en un número separado y lanzarlo en un horario diferente al resto de los cambios de 🔥.

Estoy de acuerdo con @felixfbecker
Todo suena increíble y mejoraría la calidad tanto para los desarrolladores como para los usuarios, pero el cambio className.

Ser capaz de deconstruir todas las propiedades, excepto una, sin duda causaría más confusión y sería más difícil de explicar a los nuevos usuarios que necesitan usar className porque class es una palabra clave (que pueden ver claramente cuando se comete el error, ya que tiene un color diferente) . Trabajar alrededor de la clase en la deconstrucción requiere la introducción de una nueva sintaxis o una forma completamente diferente de leer esa propiedad específica que solo funcionaría hasta que necesite usar una propiedad de descanso.
Crea muchos problemas solo para guardar cuatro caracteres.

@felixfbecker , ¿podría ser class / for en JSX y className / htmlFor en la versión JS?

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

sería

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

¡Gran plan! ¡Es bueno escuchar eso! 👏👏👏

Esto es increíble, no puedo esperar para profundizar en las cosas nuevas.

Simplifique drásticamente el sistema de eventos (#4751).

Ahora reaccionar no puede delegar el controlador a elementos personalizados, sin extender la definición de ReactDOM. https://github.com/facebook/react/issues/9242

Significa que React no puede establecer un controlador personalizado en un elemento personalizado como <x-component onMyEvent={ev => {...}} />

@gaearon
¿Tienes algún plan sobre esto?

Todos estos cambios son excelentes, pero el cambio meta más grande de todos ellos es la reducción de tamaño en mi opinión. React tiene un DX promedio, pero es lo suficientemente grande como para que descargarlo y analizarlo en redes promedio y en particular en dispositivos móviles sea un problema.

¡Podríamos tenerlo todo!

¿Reescribir la delegación del evento abriría la puerta para arreglar el #1254; donde algunos eventos degradan el rendimiento del nodo al que están conectados (lo que para React significa toda la aplicación).

Además, como posibilidad remota, ¿ha considerado tener accesorios de conjuntos de datos sintéticos? No poder escribir accesorios HTML permitidos (debido a data-*) genera una gran cantidad de errores al reenviar accesorios a los nodos DOM. Los componentes React tipificados actualmente tienen que elegir entre tipos exactos para accesorios y atributos de datos permitidos.

estoy emocionado

@ryanflorence Un poco exagerado, pero es un poco triste que nadie (que yo sepa) tuvo la idea de hacer un transformador html/css/svg -> jsx para facilitar las migraciones a React con tantos cambios triviales en el mapa HTML attrs a accesorios React. Tantas horas-hombre desperdiciadas realizando principalmente búsqueda y reemplazo :(

Es muy extraño ver lo siguiente en el mismo problema (y los comentarios):

Nuestro objetivo es hacer que React esté mejor alineado con el funcionamiento del DOM
nombre de clase → clase
Parece extraño seguir haciendo clipPath, htmlFor, tabIndex, etc.

Cuando todos estos son contrapartes directas de las API DOM

Y este argumento no pasa la prueba:

He defendido tu versión de este argumento durante años, pero ahora creo que esto es una fricción que simplemente no vale la pena. No ganas nada con eso. Solo dejar que la gente use la clase no tiene efectos negativos, excepto que

React siempre ha sido solo una capa muy delgada sobre JS. Entonces, todo lo demás, además de los corchetes angulares de JSX, era JS _y_ tenía una contraparte directa en las API de DOM para cosas directamente relacionadas con DOM: className , clipPath , htmlFor , tabIndex , etc., etc., etc.

Con la decisión de introducir class React deja de ser una capa delgada ( class es una palabra reservada en JS) y rompe con el objetivo declarado de ser más compatible con las API DOM.

Es especialmente chocante ver que desea "Migrar de onChange a onInput" porque es inconsistente con el DOM _y_ se vuelve inconsistente con el DOM al migrar className -> class .

Además, esto abre una lata llena de gusanos, ya que la gente exigirá (y ya exige) cambios en otras partes. Solo en los comentarios: ¿por qué usamos dataset en lugar de data-* ? ¿Tal vez porque data-* no es un JS válido (como class ) y porque es consistente con las API DOM ? ¿Por qué no cambiamos htmlFor ? ¿Porque for es una palabra reservada y htmlFor está en las API DOM? etc etc etc etc

Y, sin embargo, si pasamos un par clave/valor desconocido, se tratará como un atributo desde React 16. Por lo tanto, ya somos inconsistentes.

@gaearon, que también es la razón por la que React es la única biblioteca con una mala puntuación en la prueba de interoperabilidad CustomElements Everywhere: https://custom-elements-everywhere.com/
Y hay muchos problemas que piden cambiarlo: https://github.com/facebook/react/issues/11347 , https://github.com/facebook/react/issues/7249 , https://github.com/facebook /reaccionar/problemas/9230

Esto puede no ser un problema, pero ¿la similitud de React Fire con React Fiber va a ser confusa para los hablantes no nativos de inglés? A menudo he pensado que el hecho de que Newark Penn Station y New York Penn Station estén en la misma línea de tren aquí en Nueva York era una broma particularmente cruel para los turistas.

Si es una preocupación real, podría llamarlo React Flame y aún así mantener el emoji de fuego 🔥.

¿Reescribir la delegación del evento abriría la puerta para arreglar el #1254; donde algunos eventos degradan el rendimiento del nodo al que están conectados (lo que para React significa toda la aplicación).

Arreglar el #1254 de alguna forma es definitivamente algo que me gustaría ver.

Además, como posibilidad remota, ¿ha considerado tener accesorios de conjuntos de datos sintéticos?

No quiero comprometerme con algo como esto ahora porque hay una superficie más grande. Una interfaz más rica para DOM ( ariaSet , dataSet , classList ) tiene sentido, pero no está claro cuánto queremos invertir en React DOM, en comparación con una biblioteca de nivel superior que le brinda una API DOM más rica. Dado que estos cambios son más cosméticos pero tienen un área de superficie alta, me abstendría de hacerlos.

Reaccionar ardiente 🔥

@ryanflorence Un poco exagerado, pero es un poco triste que nadie (que yo sepa) tuvo la idea de hacer un transformador html/css/svg -> jsx para facilitar las migraciones a React con tantos cambios triviales en el mapa HTML attrs a accesorios React. Tantas horas-hombre desperdiciadas realizando principalmente búsqueda y reemplazo :(

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

Tan emocionados por los nuevos cambios, ustedes, los humanos de Facebook, están haciendo historia con esta migración. 50k componentes se migrarán a React Fire?
Tus suites de prueba deben ser tan estrictas <3

¿La similitud de React Fire con React Fiber será confusa para los hablantes de inglés no nativos?

tal vez también para personas con problemas de audición (o aquellos con otras condiciones que afectan la discriminación de palabras)

Gracias por compartir @gaearon , ¡es increíble!

Me encantaría ver una versión de JSX 2.0 que solucione el problema de los espacios en blanco y las líneas nuevas que se produce cuando compilamos nuestro código con Babel y TypeScript.

Se abrieron diferentes problemas y traté de contribuir, pero me dijeron que no porque el equipo de React necesita revisar todo lo relacionado con JSX.

Este problema se relaciona con el dom de todos modos, porque la forma en que traducimos jsx a js no permite lo que dice w3c.

Este es el problema https://github.com/facebook/jsx/issues/19

Mi comentario está al final.

Creo que className está bien. Que sea lo que es. No agregue insulto a la lesión.

¿Puede alguien aclarar cómo afecta esto a los controladores existentes?

Dejar de reflejar los valores de entrada en el atributo de valor

¿React seguirá teniendo entradas controladas con actualizaciones precisas event.target.value en los controladores, o esto solo afecta la lectura de valores de referencias y nodos DOM?

@nickmccurdy afecta lo que ves en las herramientas de desarrollo del navegador

@tomdale Reaccionar Ember 🔥

¡Agradable! Estoy esperando ver la lista completa de cambios en React 17.
Creo que será una nueva era de ReactJS. 🔥⚛️

@tomdale Hmm: hilo, fibra, tela; ¿Quizás se podría usar otro término relacionado con la ropa? 😆

Y, sin embargo, si pasamos un par clave/valor desconocido, se tratará como un atributo desde React 16. Por lo tanto, ya somos inconsistentes.

@gaearon, que también es la razón por la que React es la única biblioteca con una mala puntuación en la prueba de interoperabilidad CustomElements Everywhere: https://custom-elements-everywhere.com/

No, esa no es la razón (los elementos personalizados y normales son rutas de código completamente separadas). La razón es que ya teníamos el comportamiento anterior y no queríamos romper la compatibilidad con versiones anteriores a menos que el nuevo comportamiento fuera sólido. Creo que tendría sentido abordar una mejor interoperabilidad de elementos personalizados como parte de este paraguas.

¿La similitud de React Fire con React Fiber será confusa para los hablantes de inglés no nativos?

Ambos son nombres en clave internos y realmente no tienen ningún significado una vez que se completan los proyectos. React Fire es solo un esfuerzo para mejorar React DOM, y para cuando esté listo para la producción, será solo React DOM.

¿React seguirá teniendo entradas controladas con actualizaciones precisas de event.target.value en los controladores, o esto solo afecta la lectura de valores de referencias y nodos DOM?

Sí, porque event.target.value es una propiedad . Estamos hablando de dejar de actualizar los atributos . Lo que no hacen otras bibliotecas populares (AFAIK) y que causa innumerables problemas. No debería afectar su código a menos que confíe en los selectores de CSS en el valor (que probablemente sea malo de todos modos).

¡Agradable! Estoy esperando ver la lista completa de cambios en React 17.

Tenga en cuenta que no nos comprometemos a que esto esté listo para el 17. Podría ser el 18. O el 19. 😅

Es bueno ver un desarrollo constante en una biblioteca tan buena como React. 🎉 class mejorará mucho la usabilidad, vale la pena en mi opinión

@gaearon

los elementos personalizados y normales son rutas de código completamente separadas

Eso en sí mismo parece algo que arreglar también. ¿Hay alguna razón para no tratar todos los elementos de la misma manera? Esa es la intención de las especificaciones de HTML y DOM.

@justinfagnani Como se discutió anteriormente, la razón por la que no lo hicimos en ese momento fue porque no había una convención sobre cómo saber si establecer una propiedad o un atributo, y existía el riesgo de que al usar un control nos arriesgáramos a hacerlo. imposible que la plataforma web agregue nuevas propiedades al prototipo. Creo que a estas alturas ya existe algún tipo de consenso en los RFC y PR en los que @robdodson ha estado trabajando, y probablemente podamos retomarlo a partir de ahí.

👍 🔥 🔥 🔥

React Fire también debería permitirnos aplicar algunas de las optimizaciones de rendimiento inteligentes que tiene Inferno, pero que no hemos podido aplicar debido a cambios importantes. Tiempos emocionantes :)

LGTM

Relacionado con el cambio de nombre propuesto className -> class : Me encantaría una propiedad classes que tomara una serie de cadenas. Eso me ahorraría el problema de una gran cantidad de manipulación de cadenas (o el uso de nombres de clase ) en mis componentes.

Creo que la única desventaja de un accesorio classes sería que las matrices que contienen las mismas cadenas en el mismo orden provocarían una nueva representación en un componente puro, mientras que una cadena de las mismas clases CSS no lo haría. Sin embargo, sinceramente, parece un problema menor. Creo que la mayoría de los desarrolladores de React ya conocen las ventajas y desventajas de las matrices y los objetos en los accesorios.

@gaearon tiene planes para la compatibilidad con versiones anteriores? Tal vez siga el mismo camino que React Fiber, agregando advertencias sobre los cambios y dando tiempo para que las bases de código grandes se actualicen sin perder nuevas actualizaciones.

Con respecto a class y className .

Sé que no obtendremos un amplio acuerdo sobre esto de cualquier manera que vayamos. La gente tiene opiniones muy fuertes sobre este. Quiero compartir lo que estoy pensando al respecto, con la esperanza de que sea útil.

La API del componente debería sentirse idiomática

Existe un argumento común de que React "coincide con JavaScript" y, por lo tanto, se prefiere className . Creo que esta afirmación se malinterpreta sutilmente, así que me gustaría centrarme un poco en ella.

En React, ante todo, nos preocupamos de que el uso de un componente de React se sienta como JavaScript idiomático . Esto significa que si uso un componente hipotético <Table> , espero que sus accesorios sean camelCase:

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

No espero ver nombres de accesorios como row_height o row-height en la API pública de un componente . Los accesorios del componente son un objeto (algo así como una "bolsa de opciones"), y generalmente esperamos que esas opciones sean camelCase . Esto puede no ser siempre idiomático en DOM, pero el DOM no es muy consistente en muchos lugares. React se alinea con el ecosistema de JavaScript que usa abrumadoramente camelCase .

Pero ¿qué pasa con el DOM? Aquí es donde se pone espinoso.

Las propiedades DOM no son solo "atributos en JS"

En DOM, tenemos atributos y propiedades. Los atributos son las cosas que normalmente ves en HTML. Las propiedades son las cosas que normalmente establece desde JS. Pero lo más importante es que las API de DOM existen tanto para establecer propiedades como para establecer atributos , y ni siquiera siempre establecen lo mismo.

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

En muchos casos no importa. En algunos casos lo hace. Pero tal vez no en la forma en que uno podría pensar al usar React (que tiene una abstracción sobre ambos).

React no es solo establecer propiedades

Un error común es que, dado que React actualmente usa la convención camelCase para la mayoría de los accesorios DOM, significa que React está configurando las propiedades DOM. Esto está mal.

De hecho, React actualmente usa atributos para casi todos los accesorios que admite. En algunos casos, como value , esto está causando problemas (que, como mencioné, queremos revertir). En otros casos, esto es realmente genial, porque no tenemos que incluir una lista de propiedades admitidas en el paquete de React. El uso de atributos debajo del capó es lo que permitió una gran reducción de tamaño en React 16.

Mi punto aquí es que si React usa propiedades o atributos internamente es un detalle de implementación , y no tiene nada que ver con si el elemento _API_ de React DOM debe usar nombres de propiedades, nombres de atributos o incluso algunos otros nombres que tengan sentido.

Aún así, ¿vamos a usar nombres de propiedades?

Bien, las propiedades y los atributos son un detalle de implementación. Pero, ¿por qué no estandarizar el uso de nombres de propiedades DOM, ya que se crearon específicamente "para JavaScript"? ¿No es así como se diseña React API hoy?

Bueno, no del todo. Solo uno de los accesorios enumerados a continuación corresponde a una propiedad de objeto DOM real:

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

Irónicamente, el único accesorio anterior que tiene una propiedad DOM real con el mismo nombre correspondiente ( tabIndex si no estaba seguro) ¡React lo está configurando como un atributo!

Entonces, en este punto, probablemente vea que no es ni claro ni consistente. En algunos casos, las propiedades no existen (como para atributos personalizados no estándar), en algunos casos, React podría proporcionar una API más rica ( data- vs dataSet ) pero actualmente no lo hace.

En algunos casos, React elige intencionalmente desviarse ( onClick en React vs onclick propiedad DOM) porque tiene más sentido para los componentes personalizados de React. Esto se debe a que los componentes de React a menudo exponen controladores de eventos más complejos como onItemClick . Sería muy inconsistente si escribiera <Button onclick> pero <Table onItemClick> . Y <Table onitemclick> no es camelCase, que queríamos evitar en una API de componentes.

Anteriormente, expliqué que React ya no es consistente acerca de "siempre usar el nombre de la propiedad DOM", que React ni siquiera usa propiedades internamente (por lo que la regla general tampoco describe la mecánica real), y que en muchos casos, las propiedades DOM simplemente no existen, por lo que debemos seguir permitiendo el nombre del atributo.

Si no son nombres de propiedades, ¿seamos coherentes y usemos nombres de atributos?

Entonces, ¿por qué no usar solo nombres de atributos? Esto podría ser plausible. Pero ahora nos topamos con la primera consideración que mencionamos. El uso de un componente React debería sentirse como JavaScript idiomático . Pero a menudo los componentes reenvían al menos algunos accesorios al elemento DOM subyacente.

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

 // renders...

 <button
   tabIndex={1}
/>

Sería incómodo para un Button personalizado aceptar accesorios con mayúsculas inconsistentes:

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

Esto obliga al consumidor a recordar siempre si un accesorio determinado es un accesorio DOM real o solo una parte del contrato de componentes. Incluso esa distinción es confusa: un componente puede optar por pasar primero un accesorio determinado, pero luego comenzar a usarlo para obtener una lógica adicional. ¿Dónde pones el límite entre "accesorios DOM" y "otros accesorios"?

Creo que esta es la razón principal por la que es deseable que accesorios como tabIndex , cellSpacing y la mayoría de los demás accesorios relacionados con DOM sigan la convención camelCase. Es porque a menudo terminan en API de componentes.

Queremos facilitar que los componentes personalizados como Button los ajusten y los reenvíen sin "traducirlos" al nombre del atributo en el punto en el que fluyen hacia el DOM, y sin introducir accesorios que no sean camelCase en un API de componentes personalizados.

Esto también explica por qué accesorios como data-* , aria-* y los atributos personalizados son excepciones razonables (aunque podríamos crear API más ricas para ellos). Raramente se pasan a componentes personalizados. Por lo general, están demasiado acoplados al DOM para ser útiles en componentes personalizados y, en cambio, se convierten en un detalle de implementación de algo como <Modal> o <Button> con una API camelCase más rica.

Las propiedades de reacción ya no coinciden con las propiedades DOM

Si la convención de "nombre de propiedad DOM" no funcionó, necesitamos algo más. ¿Qué es? ¿Podría ser "versión camelCase del nombre del atributo"? Parece que esto casi siempre ya se verifica.

Si esto suena demasiado radical, considere que ya lo estamos haciendo. Apoyamos algo llamado srcSet . Pero el nombre de la propiedad DOM es srcset . Tenemos autoCapitalize pero la propiedad DOM se llama autocapitalize . Tenemos autoFocus pero la propiedad DOM es autofocus .

Ya nos estamos desviando de los nombres de propiedad del DOM cuando no coinciden con la convención de JavaScript camelCase. Lo que nos lleva a class .

Finalmente: className frente a class

Parte de la justificación original para convertirlo en className se debió a que React estaba configurando las propiedades DOM, y className es el nombre de la propiedad DOM.

Sin embargo, como expliqué anteriormente, React ya no usa propiedades, excepto tres o cuatro casos especiales. Más importante aún, React ni siquiera usa constantemente los nombres de las propiedades del DOM; más bien, usa nombres que se verían naturales cuando se usan desde JavaScript, independientemente de la inconsistencia de nombres internos en los nombres de las propiedades y los atributos del DOM. Y eso se debe a que React se preocupa más por mantener los nombres de accesorios para los componentes personalizados como "JavaScripty". En este sentido, tabindex no es "JavaScripty", pero tanto class como className sí lo son.

Otro argumento en contra class desde el principio fue que un código como este no era válido para ES3 (relevante para IE8):

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

Pero la mayoría ya no escribe ES3. O está utilizando una cadena de herramientas como Babel o probablemente esté apuntando a IE9+ — React ni siquiera es compatible con IE8 ahora.

Entonces, el único inconveniente que queda con class es que no puedes escribir esto:

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

Pero creo que con el tiempo, este argumento no es lo suficientemente fuerte por sí mismo. React no lo obliga a usar la desestructuración o el uso de este nombre de variable específico, y escribir algo como

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

no es mucho más esfuerzo.

Por lo general, las personas transmiten class mucho más a menudo de lo que lo leen porque muchos componentes contienen más de un <div> interno u otros elementos host. Entonces terminas escribiendo <div className> mucha más frecuencia que queriendo desestructurar class . Y, por lo tanto, el cambio a class ahorraría más escritura en el teclado de lo que introduciría.

Hay otro punto importante aquí.

Pasar class hacia abajo a través de muchos niveles no es un gran patrón en sí mismo. Es necesario para las bibliotecas, pero en el código de la aplicación a menudo conduce a componentes frágiles. Aquellos cuyos estilos fallan todo el tiempo porque hay cientos de sitios de llamada diferentes, cada uno de los cuales agrega una clase diferente, lo que provoca errores en cascada. Por lo tanto, no está claro qué tan valioso es alentar la desestructuración class en primer lugar. Creo que está bien que necesites escribir una línea más de código para leerlo desde los accesorios (o simplemente puedes usar props.class y no pensar en ello).

Si está escribiendo un componente que está muy cerca del DOM (y, por lo tanto, tiene sentido que tome class como accesorio), es probable que también desee reenviar otros accesorios. Entonces puede usar la sintaxis de descanso en la desestructuración:

// Valid in ES2018

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

Y si no necesitaba modificarlo, podría haber reenviado {...rest} sin siquiera leer class de él. Entonces, la limitación de desestructuración podría ayudar a fomentar un mejor diseño de componentes.

¿Por qué no los dos?

why not both

Finalmente, ¿no podemos admitir tanto class como className ? En cierto modo, ya lo hacemos, pero React te lo pide a gritos con una advertencia. Hay una razón para esto.

Si admitimos ambos sin advertencias, la comunidad se dividirá sobre cuál usar. Cada componente en npm que acepte una prop de clase deberá recordar reenviar ambos. Si incluso un componente en el medio no funciona e implementa solo un accesorio, la clase se pierde, o corre el riesgo de terminar con class y className en la parte inferior "en desacuerdo" con cada uno otro, sin forma de que React resuelva ese conflicto. Así que pensamos que sería peor que el statu quo y queremos evitarlo.

Resumen

Si React fuera de código abierto hoy, parece que las ventajas de permitir class (conceptualmente más cercano a lo que la mayoría de la gente espera, menos tipeo para el accesorio más utilizado) superan las desventajas (un poco más de tipeo para interceptarlo, en en cuyo caso probablemente solo querrá el operador de propagación de todos modos).

Lo que solíamos ver como desventajas (inconsistentes con las propiedades DOM) es discutible porque ya no establecemos las propiedades DOM, ni siquiera nos esforzamos por ser consistentes con ellas. En cambio, nuestro objetivo es tener una API camelCase basada en atributos en el lado de consumo de los componentes de React, en lo que ya somos casi consistentes. Y class="Button" es claramente más conveniente que className="Button" . De hecho, si la API DOM se diseñara hoy, probablemente le permitiría establecer la propiedad .class precisamente porque la restricción sobre el uso de class en una tarea como esta se eliminó en ES5, hace casi diez años.

El único gran inconveniente que queda es el costo de la migración. Evaluaremos esto cuidadosamente. Pero si estamos haciendo un montón de cambios de todos modos, podríamos hacer este también y arreglarlo para siempre. No estamos pensando en esto a la ligera y tomamos todas sus inquietudes en consideración.

Nota: esto podría tener sentido para otros nombres de accesorios de React que no coincidan con los nombres de atributos de camelCased.

@renatoagds

¿Tiene planes de compatibilidad con versiones anteriores? Tal vez siga el mismo camino que React Fiber, agregando advertencias sobre los cambios y dando tiempo para la actualización de grandes bases de código.

Como señalé:

Y tenemos más de 50 mil componentes en Facebook para mantenernos honestos sobre nuestra estrategia de migración. No podemos darnos el lujo de reescribir el código del producto, excepto algunas correcciones específicas o modificaciones de código automatizadas.

Así que definitivamente intentaremos que la estrategia de migración sea lo más fluida posible, como siempre lo hacemos. Si no es sencillo, no podremos hacer el cambio nosotros mismos.

re: className -> class, estoy bien con cualquier decisión, definitivamente puedo ver la excepción al cambio de clase para nuevos usuarios, y un beneficio adicional de líneas de código más cortas. Aunque, todavía necesitarían aprender sobre los otros nombres de camelCase.

Entonces, el único inconveniente que queda con la clase es que no puedes escribir esto:

const { class } = props;

Pero creo que con el tiempo, este argumento no es lo suficientemente fuerte por sí mismo. Reaccionar no te obliga a usar > desestructurar y escribir

const class = props.class;

no es mucho más esfuerzo.

Dos cosas (posiblemente pequeñas):

  1. ¿No es const class = props.class JavaScript no válido? No pensé que lo fuera, y en una prueba rápida a Chrome no le gustó. Además, este artículo sugiere que no es válido.

  2. Pude ver que este cambio es un área de frustración (una vez más, potencialmente pequeña) para las personas que escriben componentes como este: nvm (consulte la actualización a continuación)

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

// do stuff with oneProp, twoProp, className

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

Después de este cambio, esto tendría que ser algo como...

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

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

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

No es imposible evitar este cambio, pero es un poco más a tener en cuenta al escribir y leer componentes en este estilo.

Actualizar :

No importa,

const { class: className } = this.props;

Hace el truco.

El único gran inconveniente que queda es el costo de la migración. Evaluaremos esto cuidadosamente. Pero si estamos haciendo un montón de cambios de todos modos, podríamos hacer este también y arreglarlo para siempre. No estamos pensando en esto a la ligera y tomamos todas sus inquietudes en consideración.

Afortunadamente, esto se mitiga fácilmente si se utiliza un enfoque CSS-in-JS, como Aesthetic. ¡Gracias por la increíble escritura!

Sugerencia aleatoria con respecto a los nombres de atributos, encontré el excelente proyecto, svg2jsx es excelente para convertir SVG grandes para usar en React.

@jamesplease Lo siento, mi mente se quedó en blanco, tienes razón. Editado.

@jamespor favor tienes razón. Eso también surge con frecuencia al trabajar con JSON, por el valor predeterminado, ¡muy molesto!

const { default: defaultVal } = property

Mientras cambia el sistema de eventos, sería muy bueno ver algo similar a la función linkEvent de Inferno para que podamos manejar eventos usando accesorios en componentes funcionales sin tener que crear una función anónima en cada renderizado.

className -> class será un gran cambio para el ecosistema, numerosos componentes sin mantenimiento se volverán incompatibles y no habrá nada que pueda hacer si no puede parchearlos. ¿Tal vez tenga algún contenedor como StrictMode que deshabilite este cambio para los componentes más profundos en el árbol para proporcionar una ruta de migración gradual?

Pude ver que este cambio es un área de frustración (una vez más, potencialmente pequeña) para las personas que escriben componentes como este:

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

// do stuff with oneProp, twoProp, className

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

Simplemente no lo desestructuras.

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

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

@gaearon

si React usa propiedades o atributos internamente es un detalle de implementación

Eso también parece un problema, sinceramente. Los elementos DOM pueden comportarse y se comportan de manera diferente en algunos casos dependiendo de si está configurando atributos o propiedades. No es posible que React conozca todas las diferencias, pero los usuarios de elementos pueden conocer los elementos que usan. El control explícito sobre propiedades, atributos y eventos permitiría a los autores salir de esta situación.

@justinfagnani Si tiene cosas específicas que le gustaría que cambiemos, ¿le importaría presentar un problema por separado con una API que sugiera? Esto suena un poco fuera del alcance de este problema.

@sompylasar

className -> class será un gran cambio para el ecosistema, numerosos componentes sin mantenimiento se volverán incompatibles y no habrá nada que pueda hacer si no puede parchearlos. ¿Tal vez tenga algún contenedor como StrictMode que deshabilite este cambio para los componentes más profundos en el árbol para proporcionar una ruta de migración gradual?

Estoy de acuerdo, y todavía estamos sopesando los pros y los contras. Nada está finalizado.

Pero en la práctica, el problema de los componentes no mantenidos no es nuevo: surge cada lanzamiento principal de React porque algo cambia en los principales por definición (no podemos avanzar de otra manera, y no podemos darnos el lujo de mantener todo el código heredado en el paquete para siempre, a diferencia de, por ejemplo, los entornos de servidor). El mismo problema surgió cuando PropTypes se movió a un paquete separado y volverá a ocurrir con el cambio de nombre del ciclo de vida UNSAFE_ . Los paquetes sin mantenimiento se bifurcan o se parchean. Nos damos cuenta de que es un gran sumidero de tiempo, y es por eso que evitamos hacer más de una gran carrera en un año. Para las personas que no pueden permitirse el lujo de ayudar, normalmente esperar unos meses antes de pasar a una nueva especialidad es la mejor estrategia porque los primeros en adoptar allanan el camino y reviven los paquetes abandonados. Luego avanzamos todos juntos.

Una vez más, entiendo mucho su vacilación, pero esto no es principalmente diferente de otros cambios importantes que sucedieron en el pasado o que podrían ocurrir en el futuro. Como siempre, pondremos mucho esfuerzo y énfasis en los scripts automatizados que puede ejecutar para convertir la mayor parte de su código base, y que también puede ejecutar en otros paquetes (y enviarles relaciones públicas, o bifurcarlos en su último estado ).

Independientemente de su decisión, un argumento más en contra class es la capacidad de búsqueda. ¿Cuántos falsos positivos le dará la búsqueda por class cuando quería encontrar componentes que usan clases CSS en código ES6 que usa componentes de clase JS? Sí, puede buscar class={ , pero ¿qué pasa con la desestructuración de accesorios en JSX que se crean como un objeto en JS? (Estoy en contra del uso intensivo de la desestructuración de accesorios, pero aún se usan). Por supuesto, necesitamos mejores herramientas de búsqueda basadas en AST que tengan en cuenta el contexto en los editores de código, pero por ahora solo tenemos texto y expresiones regulares. Por supuesto, los sistemas de tipos pueden ayudar a rastrear el paso de objetos, pero una gran población no los ha adoptado.

Algo sobre el uso de una palabra reservada simplemente no me sienta bien, incluso si no causa ningún problema ahora ; ¿Podemos decir con seguridad que rest.class (por ejemplo) no será significativo para el idioma en x años?

@GeordieP Si funciona hoy, no puede romperse mañana. Ese es el principio central de cómo se está desarrollando JavaScript y la razón de muchas de sus idiosincrasias.

@gaearon Bastante justo, entonces. Si es una victoria lo suficientemente grande, digo que lo haga.

@sompylasar Normalmente busco className= o className: , parece que ambos también funcionarían con class .

Deshazte de className y, por el amor de Dios, htmlFor . No soy un desarrollador de DOM, por lo general hay algo muy, muy mal si tengo que acceder a los métodos DOM nativos. El mayor desafío que tengo para incorporar personas a React es la abstracción que JSX hace sobre el DOM y sus extraños atributos HTML de reemplazo. Todo se está transpilando, no hay motivo para preocuparse por las palabras reservadas en este momento. OMI.

No estoy seguro de que esto agregue algo a la discusión existente, pero parece que debería haber una mejor razón para cambiar className .

¿Vale la pena salvar a los principiantes de React de un nombre poco intuitivo para que todos tengan que actualizar sus proyectos y su comportamiento?

Como alguien que usa la desestructuración generosamente, tener que recordar esta nueva excepción a la regla es probablemente un contratiempo mental mayor que la rara ocasión en que escribo class en lugar de className .

Además, ¿no se confundirían los principiantes con la gran cantidad de material (como blogs/repos/etc) que usa className actualmente?

Finalmente, como dijo @sompylasar , esto perjudica la capacidad de búsqueda dentro de mi base de código.

Tal vez este sea un argumento de tipo tabulaciones vs espacios, pero no entiendo totalmente por qué es necesario este cambio. Parece un gran costo por poca ganancia a menos que esto sea parte de un cambio más grande en la forma en que desea modelar la API a lo largo del tiempo. Dicho esto, seguro que usaré lo que decidas 😅.

Un poco exagerado, pero es un poco triste que nadie (que yo sepa) tuvo la idea de hacer un transformador html/css/svg -> jsx para facilitar las migraciones a React con tantos cambios triviales para asignar atributos HTML a Reaccionar accesorios.

@jxub : construí un convertidor de HTML a JSX como parte de un hackathon en 2014: https://magic.reactjs.net/htmltojsx.htm. Sin embargo, no estoy seguro de si maneja bien SVG. El proyecto del hackathon consistía en hacer un script que "ajaxificaría" un sitio HTML simple usando React (https://github.com/reactjs/react-magic) y parte de eso me requería construir una forma de crear un componente React. de un fragmento de HTML, así que lancé la parte de HTML a JSX como una página independiente separada.

Todavía nos preocupamos por admitir IE11, pero es posible que no intentemos suavizar algunas de las diferencias existentes en el navegador, que es la postura adoptada por muchas bibliotecas de interfaz de usuario modernas.

@gaearon : ¿cuáles son algunos ejemplos de bibliotecas de interfaz de usuario modernas que no suavizan las diferencias del navegador? Para mí, esa es una de las principales razones para usar una biblioteca.

Teoría de la conspiración: todo este nombre de clase / noticias de clase es una cosa controvertida brillante a la que todos prestarán atención de inmediato y discutirán. Es para llamar la atención sobre el proyecto de reelaboración en su conjunto, o distraer la atención de algo más grande que está sucediendo en las sombras, o dar una cosa que luego se pueda retractar mientras que el resto se aceptará, como en la siguiente anécdota:

El gran artista teatral Tyshler, creando bocetos de paisajes, en la esquina dibujando un pequeño perro verde. Y cuando uno del comité de admisiones preguntó: “Me gusta todo, pero ¿dónde está este perro?”, la artista con un suspiro de pesar la emplastó.

Las verdaderas razones detrás de este cambio no están claras, pero ya han disparado la popularidad de este nuevo proyecto de actualización y el rumor de la comunidad sobre React.

Sería bueno si la compatibilidad con los oyentes de eventos pasivos estuviera dentro del alcance de React Fire, que es una característica importante en dispositivos móviles.

6436

Gracias por todo su arduo trabajo en esto, pero reconsidere className -> class .

Todos alguna vez fuimos novatos en React y className no nos impidió aprender y amar React.

Recuerdo cuando estoy usando vue con jsx, ya tenían class no className , no estoy de acuerdo si className se cambiará a class , porque React es pionero en Virtual DOM , y representa el propio DOM.

Adjunte eventos en la raíz de React en lugar del documento

@gaearon ¿Significa esto que en un entorno de prueba no tendré que agregar elementos al documento para poder enviar eventos reales del navegador y llamar a los controladores asociados a ellos? Tener que hacer esto es muy contrario a la intuición y estoy seguro de que ha sido la causa de que muchos desarrolladores que no están familiarizados con las funciones internas de React se confundan, pierdan mucho tiempo escribiendo pruebas e incurran en simulación de eventos y prácticas de prueba deficientes.

Lo que me lleva a otra nota, ¿podemos hacer algo con react-dom/test-utils ? Estoy especialmente interesado en la posible eliminación de Simulate dados todos los problemas asociados que todos conocemos y, por supuesto, hacer los cambios necesarios en react-dom para que realmente no sea necesario. ya no. ¿Podría estar dentro del alcance?

/cc @kentcdodds

Me encanta la dirección y la visión general que está tomando React Fire. Hasta ahora, parecen grandes cambios por los que trabajar.

Me encantan la mayoría de los cambios anunciados, pero soy escéptico sobre el cambio className .

React no lo obliga a usar la desestructuración o el uso de este nombre de variable específico, y escribir algo como (... fragmento de código...) no es mucho más esfuerzo.

Si bien no es mucho esfuerzo escribirlo, en mi experiencia actual, esperaría que fuera _mucho_ más difícil de explicar a otros desarrolladores (especialmente a los desarrolladores de otros idiomas). Por otro lado, en todos los años que usamos React en nuestra empresa, supongo que solo uno o dos desarrolladores se confundieron con className y simplemente aceptaron esto como API de Reacts para configurar los nombres de clase en un par de minutos.

(En mi opinión personal, aunque _amo_ destruir, la sintaxis de cambio de nombre a veces se siente rara en sí misma para los principiantes, porque es diferente al cambio de nombre en las importaciones, que se ve bastante similar y se puede combinar con cosas como valores predeterminados. Uno _podría_ simplemente no usar la destrucción entonces , pero eso sería una _gran_ excepción a todos los demás códigos que escribimos actualmente en nuestra empresa. La experiencia de otros puede diferir, por supuesto, pero esa es mi opinión sobre el problema 🙃).

estupendo

También escéptico sobre el cambio className . Es uno de los cambios más pequeños en el esquema de las cosas, pero está atrayendo una gran parte de la discusión de comentarios aquí.

¿Realmente vale la pena gastar tanto capital político en un cambio, cuando hay tantas otras cosas buenas que se están anunciando?

Desde mi punto de vista, si estás tomando una decisión en la que parte de la justificación es "y escribir algo como... ...no es _eso_ mucho más esfuerzo", esa decisión tiene que tener una _gran_ ventaja, y el cambio className -> class simplemente no se compara con todo lo demás que se ha anunciado.

este será un gran avance en 🔥 React Fire

Acerca class v/s className , creo que deberíamos recordarnos que JSX ≠ React.

Dado que JSX es un _DSL_ diseñado para parecerse a HTML, es mejor mantenerlo lo más parecido posible a HTML. De acuerdo, se llama className en la API DOM, pero la mayoría usa JSX probablemente porque no quieren tratar con la API DOM directamente.

Si tiene más sentido que la API de React coincida estrechamente con la API de DOM, entonces espero que esté bien/es posible hacer el mapeo en la transpilación:
<img src="avatar.png" class="profile" />React.createElement("img", { src: "avatar.png", className: "profile" }) .

Sería muy valioso hacer de la sintaxis JSX un superconjunto limpio de HTML.

Para agregar a lo que ha dicho @mhenr18 .

Estado actual de las cosas:

  • Reaccionar es inconsistente
  • API es camelCase

Estado de cosas propuesto:

  • Reaccionar es inconsistente
  • API es camelCase
  • className -> class

Beneficios percibidos:

Si React fuera de código abierto hoy, parece que las ventajas de permitir la clase (conceptualmente más cercano a lo que la mayoría de la gente espera, menos tipeo para el accesorio más utilizado) superan las desventajas (un poco más de tipeo para interceptarlo, en cuyo caso tendrá que probablemente solo quiera el operador de propagación de todos modos).

Desventajas reales:

  • todo el ecosistema que depende de className deja de funcionar (gran esfuerzo de actualización)
  • todo el vasto cuerpo de libros, tutoriales, ejemplos, código, publicaciones, artículos se vuelve ligeramente inválido
  • el único JS válido que queda es la escritura adicional : const {class: cls} = props . Todos los demás casos de uso posibles en JS simple se vuelven inválidos
  • React API sigue siendo inconsistente y rompe otras suposiciones (por qué htmlFor no for etc.)

Si yo fuera gerente de producto, mi reacción inmediata al cambio sería: ¿qué?

@gaearon Es posible que ya haya considerado esto, etiquete las relaciones públicas con "Reaccionar fuego" o una palabra clave similar.

Los problemas generalmente están etiquetados correctamente, los RP a veces no los tienen. Esto ayuda a los posibles contribuyentes.
Esto proviene de mi experiencia cuando intentaba leer el historial de git en busca de compromisos relacionados con React Fiber y React Reconciler durante todo el desarrollo de Fiber. Ayuda a aquellos de nosotros que estamos tratando de averiguar qué está pasando y ver si podemos contribuir de alguna manera.

También creo que cambiar el nombre className a class causará un gran esfuerzo de migración y problemas para los nuevos desarrolladores.
El atributo className es tan visible y tan utilizado que literalmente romperá todas las bibliotecas que dependan de react.
Y esto no es suficiente, la mayoría de los tutoriales estarán rotos. Un nuevo dispositivo para copiar y pegar de un artículo se preguntará "¿por qué no funciona? Dice que className no es un accesorio válido".
Así que el mayor tiene que ayudar y no hemos ganado nada, porque todavía tenemos que explicar por qué no funciona como cabría esperar.
Y de verdad, explicar que tiene que usar className para definir clases en el componente lleva menos de un minuto y es fácilmente comprensible. Explicar por qué cambiaron de className a class a cada desarrollador lleva mucho más tiempo y genera más frustración.

Todos los esfuerzos necesarios para una sola palabra.
No cambiará nada en la forma en que reacciona.
No impulsará el desarrollo de react-dom.
No aumentará la productividad de los desarrolladores que trabajan más de una semana con React.
Simplemente romperá todo.

Por favor piénsalo, ¿realmente vale la pena?

He estado usando babel-plugin-react-html-attrs durante años y me ha servido bien, no creo que cambiar el nombre className a class sea una buena idea. Se logra mejor con un complemento como el que mencioné.

¿No había un complemento de Babel para manejar toda la situación " class v className " / " for v htmlFor "?

Espero que sea posible admitir los atributos html tal como están y, al mismo tiempo, mantener la compatibilidad con versiones anteriores con las decisiones de nombres ya tomadas.

El hecho de que ya existan complementos de Babel para realizar la conversión es quizás una prueba de que debería ser posible admitirlo en el transpiler JSX principal. Pero convertirlo en una especificación oficial haría las cosas mucho más fáciles y confiables para todos.

No estoy al tanto de las partes internas de React, por lo que no puedo decir mucho sobre la viabilidad real. Solo expresando cómo creo que "debería ser" en términos de facilidad de uso.

Reconsidere className frente a class . Como se ha dicho anteriormente, la ganancia es casi inexistente, pero hay desventajas reales.

Uno es que para nosotros usar Haxe como lenguaje para escribir aplicaciones de reacción, esto no solo sería un cambio importante, sino que simplemente nos impediría escribir _cualquier_ aplicación de reacción.

class es una palabra clave reservada en la mayoría de los lenguajes de programación, y simplemente ya no podríamos manipular este accesorio, lo que hace que la aplicación de reacción sea casi imposible (buena suerte creando una real sin manipular clases). Lo mismo ocurre con htmlFor vs for , lamentablemente (este es realmente feo pero estoy agradecido de que exista).

Ah, por cierto, capacidad de búsqueda... Imagina que buscas en Google "clase React", obtendrás señales mixtas: componentes de la clase React, atributo de la clase React. Si busca en Google "React className", obtendrá documentación desactualizada (las personas mencionaron anteriormente la gran cantidad de trabajo de actualización generado por este cambio además de las actualizaciones de código).

¿El objetivo de este proyecto es generar más trabajo para la comunidad y más ruido y señales mixtas para Internet? Espero que no.

Sí, el ecosistema Web y JavaScript se esfuerza por mantener la retrocompatibilidad con errores estúpidos del pasado, pero esta lucha por la retrocompatibilidad es lo que le permitió crecer hasta tal escala sin una gran fragmentación.

Entiendo que no hay progreso sin cambio, y yo mismo adopté el lema de los primeros FB de romper cosas para moverse rápido (también tener un plan de cómo volver a armarlas de antemano).

Si está siendo tan persistente que este cambio es realmente necesario, simplemente diga la verdadera razón del cambio. No puede ser algo "difícil de aprender", suena demasiado superficial para el poderoso equipo de React Core. Definitivamente deberías tener algo en mente.

@sompylasar Normalmente busco className= o className:, parece que ambos también funcionarían con class.

Además, buena suerte haciendo eso directamente en github =/

He leído todos los comentarios aquí. Estoy bien con los cambios, pero no estoy seguro acerca de class . La razón principal es que no funcionará con planes para JSX 2.0. sobre la notación abreviada (como la que tenemos ahora en los objetos).
Todo lo demás parece ser mejoras muy agradables.
Esperando la decisión final :) ¡Gracias por sus increíbles esfuerzos amigos!

En uno de tus comentarios, mencionaste “si funciona hoy, debería funcionar mañana”. Tenga esto en cuenta antes de mi pregunta;).

Mantengo una biblioteca de interfaz de usuario llamada RMWC https://jamesmfriedman.github.io/rmwc/ que apunta a todas las versiones de React desde la 15.4. Pude mantener una superficie API unificada, pero cambiar className a class, onChange a onInput y revisar el sistema de eventos hará que esto sea casi imposible de continuar.

¿Existe alguna posibilidad de una capa "compatible" que pueda traducir algunas de estas cosas debajo del capó? Entonces puedo escribir en cualquier versión que sea reaccionar al fuego pero continuar ejecutándome en un tiempo de ejecución más bajo.

Si no, espero que mi código extraño se vuelva más extraño. 👀

si className realmente tiene que cambiar a class , cambie también htmlFor a for .
ya que class y for originalmente no eran válidos cuando desestructuramos props .

Si React tiene su propia API que normaliza una gran cantidad de nombres de atributos para hacer una API consistente, entonces seguramente className es perfecto para eso. Un aprendizaje idiomático adicional además de los modismos camelCase, más el hecho de que se asigna al nombre de la propiedad DOM (como algunos de los otros atributos JSX) seguramente está bien en comparación con tener que desestructurarlo como un caso especial cada vez que usa un objeto de utilería con él encendido.

Siento que, hasta ahora, has escuchado muchas opiniones vocales en contra del status quo ("¡¿Por qué no podemos tener clase?!"), Mientras que todos los que estaban felices de usarlo se quedaron callados; en línea con el viejo adagio de que es mucho más probable que las personas den críticas negativas que positivas. Personalmente, creo que una pequeña curva de aprendizaje además de muchas otras es mucho mejor que una cubierta especial de este accesorio cada vez que aparece.

Creo que me gustaría ver un poco más de democracia a su alrededor. Creo que este cambio muy específico puede ser realizado por un comité (esencialmente, fue un pseudo comité el que hizo que usted considerara este cambio), y estoy feliz de estar en el bando perdedor. Solo para que afecte a la menor cantidad de personas en el día a día.

Ps, todo lo demás se ve genial por cierto, especialmente las cosas del evento 👌🏻

esperando nuevas actualizaciones

@gaearon ¿Vale la pena considerar que tu propio ejemplo:

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

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

contiene un error y no funcionaría como esperabas? Puede que no sea tan sencillo como "Simplemente no lo desestructura".

¿Soy el único al que no le preocupaba que la clase fuera className? Si me preguntaras qué problemas tenía reaccionar, eso nunca se me pasaría por la cabeza.

Aún así, las actualizaciones son gratuitas y me encantan las gratuitas.

¿Soy el único al que no le preocupaba que la clase fuera className?

No estoy nada preocupado por la clase. Los errores sutiles con IE11 van a ser más divertidos (y, sin embargo, estoy más que bien con estos cambios)

Sería bueno si la compatibilidad con los oyentes de eventos pasivos estuviera dentro del alcance de React Fire, que es una característica importante en dispositivos móviles. #6436

Estoy de acuerdo. Definitivamente está dentro del alcance de este trabajo.

Hola @gaearon , antes que nada, gracias.

¿Ha considerado hacer una encuesta para recopilar información sobre cómo las personas usan React y qué API se usan y qué es confuso?

Si bien React es, con mucho, mi pila de desarrollo frontend favorita, encuentro que hay algunos problemas cuando se aprende y se usa por primera vez. No quiero simplemente exponer lo que la gente a la que enseñé encontró confuso personalmente.

Descubrí que es útil en proyectos en los que he estado involucrado personalmente (Node, Bluebird, etc.).


En términos de lo que personalmente me gustaría ver en el núcleo: me encantaría un mejor soporte de inyección de dependencia no global más simple, un manejo de eventos mejor y más consistente (que ya está discutiendo).

¿Ha considerado hacer una encuesta para recopilar información sobre cómo la gente está usando reaccionar y qué API se están usando y qué es confuso?

Creo que react-native tiene un canny.io No me di cuenta de que react no lo tiene

Mantengo una biblioteca de interfaz de usuario llamada RMWC https://jamesmfriedman.github.io/rmwc/ que apunta a todas las versiones de React desde la 15.4. Pude mantener una superficie API unificada, pero cambiar className a class, onChange a onInput y revisar el sistema de eventos hará que esto sea casi imposible de continuar.

¿Existe alguna posibilidad de una capa "compatible" que pueda traducir algunas de estas cosas debajo del capó? Entonces puedo escribir en cualquier versión que sea reaccionar al fuego pero continuar ejecutándome en un tiempo de ejecución más bajo.

Empatizo con sus preocupaciones (también escribí mi parte justa de las bibliotecas). Sin embargo, dado que hay tantas ventajas y desventajas al cambiar cualquier cosa, tendemos a equivocarnos al esforzarnos en ayudar a las personas a actualizar en lugar de ayudar a las personas a admitir múltiples versiones. No significa que no hagamos eso en absoluto (lanzamos un polyfill para los autores de la biblioteca para los cambios del ciclo de vida en 16.3), sino que no optimizamos para este caso de uso.

Mi sugerencia es cortar una nueva especialidad cuando cortamos una nueva especialidad si algo es incompatible. Las personas pueden seguir usando las versiones principales antiguas de su biblioteca si así lo desean. Sé que es más difícil de mantener, especialmente si continúas desarrollándolo, pero es cuestionable si una sola base de código hacky es mejor que dos bases de código divergentes pero consistentes.

@jamesmfriedman debería ser posible (y no demasiado complicado) actualizar (automáticamente) con un codemod) a la nueva API y luego (como parte del proceso de compilación) transformar (nuevamente con un codemod) a la antigua API. Luego envíe ambos paquetes y exíjalos dinámicamente según la versión de React.

Eso es algo de trabajo, pero se puede hacer una vez (¿como un complemento de paquete web o un script de instalación de npm, por ejemplo?) Y no debería ser difícil. Supongo que es el tipo de cosa que se lanza una vez y se usa en todas las bibliotecas.

Como una capa de compatibilidad de tiempo de compilación específicamente para bibliotecas.

Apoyo eliminar htmlFor for for.

¿Crees que una versión de puente que admita tanto className como class sería una buena idea? Permitiría a los desarrolladores usar código React de terceros más antiguo, mientras que su código de origen actual puede estar orientado hacia el futuro. Una vez que el tercero se actualiza, es tan fácil como eliminar el paquete puente para tener un React DOM completamente optimizado.

React API sigue siendo inconsistente y rompe otras suposiciones (por qué htmlFor not for, etc.)

Creo que te perdiste la última oración cuando dije que for también debería cambiar. Entonces creo que seremos totalmente coherentes con los "nombres de atributos en mayúsculas y minúsculas", excepto uno o dos atributos SVG raros. Que también podemos cambiar.

¿No había un complemento de Babel para manejar toda la situación de "clase v className" / "for v htmlFor"?

Veo bastantes menciones de esto, así que me gustaría aclararlo. Un complemento de Babel no es un buen lugar para hacer esta conversión porque no funciona para casos como

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

Tampoco tiene sentido que pase class pero obtenga className en accesorios del componente. O, si el complemento solo apunta a elementos de la plataforma, sería extraño que reemplazar button con Button cambie lo que compila el accesorio class .

El uso del complemento de Babel para esto solo oscurece la semántica del código que está escribiendo y genera más confusión. En mi opinión, es una solución peor que permitir solo className o class .

Dato curioso: así funcionaba una versión muy antigua del compilador JSX. Este comportamiento se eliminó debido a lo confuso que es.

Cambios impresionantes. . .

¡Asombroso! Gracias a todos los colaboradores por trabajar para traer actualizaciones tan emocionantes.
No tenía idea de que className > class fuera un escándalo tan grande. Personalmente me he acostumbrado.

El tamaño del paquete reducido y el sistema de eventos actualizado suenan realmente prometedores. ¡Súper emocionado!

Tengo muchas ganas de separar los polyfills del sistema de eventos como paquetes separados.
Pero si className > class es demasiado radical, ya sabes, React tiene un impacto demasiado amplio.
¿Llevará esto a lo imprevisto de muchos sistemas?

Sería bueno eliminar un tercio de React DOM.

Será genial usar React en el desarrollo de aplicaciones web.

También sería bueno que el espacio de nombres reaccionara con accesorios específicos como key y ref . p.ej

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

esto se ha discutido aquí: https://github.com/facebook/jsx/issues/66

@elado Si bien puede ser algo que queramos hacer en el futuro, creo que está fuera del alcance porque afecta a la API no específica de DOM.

Si bien es emocionante, especialmente la reducción en el tamaño del paquete, que siempre es bienvenida. Mi preocupación es que la gente de Facebook está subestimando la inercia, el dolor y la fragmentación que los cambios en la API pueden causar en el ecosistema y la comunidad.

Es cierto que tienen una gran cantidad de componentes en FB de los que preocuparse, pero la ventaja que obtuvieron, y supongo que aquí, es su dependencia mínima de las bibliotecas de reacción de código abierto externas, ya que probablemente construyeron la mayoría de sus componentes internamente. Para las otras personas que usan muchas bibliotecas de código abierto, realmente tomó mucho esfuerzo, espera y frustración sacar Proptypes de muchas bibliotecas (y hablo de una experiencia real de actualizar una gran base de código de reacción). Moverse rápido y romper cosas puede no ser aplicable para las personas que desean construir negocios estables con recursos limitados.

Realmente disfruto reaccionar, la API es simple y personalmente no me tomó tiempo aprender y adaptarme a su sintaxis. Por lo tanto, realmente insto al mantenedor a que evalúe cuidadosamente los pros y los contras de cualquier cambio importante en todo el ecosistema y piense de manera pragmática si el cambio justifica forzar la reescritura de todo el ecosistema.

Aparte de eso, realmente aprecio el esfuerzo de construir, mantener y actualizar React, y la pasión de los ingenieros detrás de esto :)

Estas futuras {...actualizaciones} son 🔥

className -> class : no creo que sea una situación rara cuando el atributo de clase se define fuera de la declaración de JSX/objeto. En tales situaciones, tendremos que usar diferentes nombres para la misma cosa, lo que producirá inconsistencias, aumentará la complejidad del código y la carga cognitiva.
El cambio sugerido no eliminará la discrepancia entre el atributo y el nombre de la propiedad de nuestras bases de código; existirá en algún lugar debido a las limitaciones de sintaxis o cuando se trabaje con DOM nativo. Ha sido bueno que hayamos "estandarizado" (y bien establecido en este punto) una solución alternativa para este problema de nombres.
Actualmente className se puede usar consistentemente en todas partes, siempre refiriéndose a lo mismo, incluso cuando se trabaja con DOM nativo. En realidad, la reacción puede ser literalmente el único lugar donde nos veremos obligados a usar class para referirnos al atributo de clase.
className parecía bastante innecesario y un poco confuso desde el principio, pero resultó ser bastante práctico más tarde y relativamente fácil de acostumbrarse.

También me desharía del objeto adicional { __html } por dangerouslySetInnerHTML , ya que parece realmente innecesario, pero es posible que no valga la pena los problemas relacionados con la migración (y tal vez no relacionados con este problema).

Si bien los otros cambios generan muchas menos emociones, son mucho más interesantes e importantes, así que gracias al equipo de Facebook por el esfuerzo.

Cuantos más cambios importantes, más tiempo llevará actualizar las aplicaciones de los usuarios reales. Personalmente, ya estoy bastante por detrás del último gran React (lo que me entristece), porque las versiones anteriores de React tienen cosas rotas que luego requieren bibliotecas de las que dependo para actualizar, lo que luego presenta demoras.

Idealmente, me gustaría estar en el escenario que:

  • La biblioteca Downstream React reescribe el código en la nueva versión, presentando un error para mi caso de uso
  • React agrega una nueva característica genial / reducción de paquetes
  • La versión antigua de la biblioteca sigue siendo utilizable en el nuevo React
  • Yay, puedo usar la nueva función justo después de que se inicie React y solo esperar a que la biblioteca solucione el error

En la práctica es más como:

  • La biblioteca reescribe el código y presenta un error
  • React lanza un nuevo cambio de última hora
  • La antigua biblioteca ya no funciona.
  • La nueva biblioteca eventualmente se actualiza
  • El error aún puede estar presente
  • Estoy atascado en React obsoleto en lugar de (para citar a Ken Wheeler) "el nuevo atractivo" durante mucho tiempo.
  • Me siento triste :(

Desde la "perspectiva del código de envío", cada actualización importante se convierte en una gran deuda técnica molesta que implica actualizar todas las dependencias, volver a probar todo y luego buscar nuevos errores para ver si hay una solución. A menos que haya una vulnerabilidad crítica o que sea realmente poco práctico hacer algo (y el listón está alto), se le quita prioridad.

Desafortunadamente, a pesar de haberse desprendido de su paradigma 0.x y de haber tratado de ser una biblioteca web central, React sigue produciendo números de versión, lo que significa que se pasa mucho tiempo ejecutándose para detenerse.

Básicamente, lo que estoy diciendo es, por favor, intente planificar una API que permita que los grandes cambios futuros no se rompan.

(Además, el asunto de IE11 es triste porque está desaprobando un navegador que no es EOL; última versión hace 52 días. Creo que el equipo de React encontrará que esto solo empuja el trabajo al equipo de Facebook y a todos los equipos de bibliotecas internas y externas para mitigarlo. en lugar de).

@urugator

También me desharía del objeto adicional { __html } para peligrosamente SetInnerHTML ya que parece realmente innecesario

Esto está diseñado intencionalmente para ser explícito y difícil de usar accidentalmente. Si se elimina, cualquier dato no desinfectado puede pasarse accidentalmente a peligrosamente SetInnerHTML.

@philipwhiuk

Básicamente, lo que estoy diciendo es, por favor, intente planificar una API que permita que los grandes cambios futuros no se rompan.

Los cambios importantes son necesarios para mejorar la tecnología, y React lo hace de manera responsable con lotes poco frecuentes de cambios importantes. Sin cambios importantes como la eliminación de componentWillReceieveProps, no tendríamos grandes cosas como React Suspense, y el software en la comunidad sería más difícil de mantener con las API antiguas para siempre. Si actualiza una versión principal a la vez, debería estar bien.

Además, lo de IE11 es triste porque está desaprobando un navegador que no es EOL: última versión hace 52 días.

Nadie está desaprobando IE 11. La versión actual de React en realidad requiere polyfills para algunas funciones en IE 11, por lo que los cambios sugeridos probablemente tendrían el mismo efecto en el desarrollo de IE 11. https://reactjs.org/docs/javascript-environment-requirements.html

También me desharía del objeto adicional { __html } para peligrosamente SetInnerHTML ya que parece realmente innecesario

@urugator : por lo que vale, internamente en Facebook, el uso más común de __html es insertar HTML renderizado por el servidor en un árbol de componentes de React. Para ese caso de uso, construimos los objetos __html del lado del servidor y tenemos reglas de pelusa contra hacerlo del lado del cliente. Del lado del servidor, tenemos métodos que serializan XHP a objetos con propiedades __html . Eso garantiza que no introduzcamos agujeros de seguridad en ninguna parte, ya que XHP es muy similar a JSX (en realidad, fue la principal inspiración para JSX) y también tiene protección XSS.

Esencialmente, los objetos __html marcan una cadena de HTML que sabemos que se ha desinfectado en algún lugar y es seguro insertarlo directamente en el DOM. Una cadena sin procesar es más difícil de manejar: ¿cómo puede saber si se ha desinfectado o si alguien devolvió accidentalmente una entrada de usuario sin procesar (y, por lo tanto, introdujo un agujero XSS)?

Entonces sí, es intencionalmente difícil de usar, porque no debería haber muchos casos de uso en la mayoría de las aplicaciones, y los casos de uso deberían estar razonablemente contenidos. En general, no debe construir el objeto __html directamente en su componente React, sino que debe tener alguna función que lo devuelva (vea cómo los documentos usan una función createMarkup : https://reactjs. org/docs/dom-elements.html#peligrosamentesetinnerhtml)

Mi preocupación es que la gente de Facebook está subestimando la inercia, el dolor y la fragmentación que los cambios en la API pueden causar en el ecosistema y la comunidad.

Gracias por mencionar esto. Entiendo perfectamente de dónde vienes. Pero me gustaría señalar que la mayoría de las personas en el equipo de React han estado usando React fuera de Facebook antes de ser contratados, a menudo en aplicaciones grandes. Así que creo que esto nos ayuda a empatizar con el tipo de problemas que afectan a nuestros usuarios de código abierto. He usado React durante dos años y recuerdo muy bien la fragmentación causada, por ejemplo, por el cambio de contexto padre/propietario. La clave fue tener una buena estrategia de migración, y lo mismo se aplica a todos los cambios anteriores.

Es cierto que tienen una gran cantidad de componentes en FB de los que preocuparse, pero la ventaja que obtuvieron, y supongo que aquí, es su dependencia mínima de las bibliotecas de reacción de código abierto externas, ya que probablemente construyeron la mayoría de sus componentes internamente.

Históricamente, esto ha sido cierto para el lado del producto del desarrollo. Sin embargo, desde que se creó Yarn y se integró con nuestro repositorio web, hemos visto un número cada vez mayor de componentes de terceros utilizados en las páginas de herramientas internas, que por sí mismas tienen un área de superficie mucho más grande que los productos de consumo de Facebook. Por lo tanto, también necesitaremos una estrategia para la migración gradual en paquetes de terceros.

A diferencia de muchas otras empresas, usamos la misma versión de React en todo el código base. Así que también tenemos desafíos únicos (por ejemplo, no podemos simplemente "esperar" con la actualización de algunos productos). Esto sin duda agregará más presión sobre nosotros para tener una buena estrategia de migración y servirá como una prueba de estrés.

Para las otras personas que usan muchas bibliotecas de código abierto, realmente tomó mucho esfuerzo, espera y frustración sacar Proptypes de muchas bibliotecas (y hablo de una experiencia real de actualizar una gran base de código de reacción). Moverse rápido y romper cosas puede no ser aplicable para las personas que desean construir negocios estables con recursos limitados.

En caso de que tengas curiosidad, todavía tenemos código como

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

en nuestra base de código porque tampoco podemos darnos el lujo de migrar a un "borrón y cuenta nueva". Pero las personas que comienzan con React hoy, así como las partes más modernas de nuestra base de código, no tienen que cargar con ese peso. Así es como lo pensamos: queremos elegir mejores valores predeterminados para los nuevos usuarios de React, pero tener una buena historia de migración para nosotros y para todos los demás, incluso si algunas partes pueden ser pirateadas.

Es posible que no haya comunicado esto lo suficientemente claro, así que me disculpo. Cualquier cambio importante necesitará una estrategia de migración sofisticada y bien ejecutada que tenga en cuenta que las bibliotecas de terceros tardarán mucho tiempo en actualizarse, es posible que deban coexistir diferentes versiones, etc. Por ejemplo, con class el El plan no es solo cambiarlo de la noche a la mañana. Si queremos hacerlo, querremos ser inteligentes sobre cómo implementarlo, posiblemente con un período de gracia en el que permitimos que ambos, o un ayudante, lo haga más fácil, y luego eliminar gradualmente el nombre anterior. . Todavía no tengo una estrategia específica, pero está claro que el cambio es inviable sin una buena estrategia, tanto para nosotros como para usted. Esto es algo que nos tomamos muy en serio.

(Además, el asunto de IE11 es triste porque está desaprobando un navegador que no es EOL; última versión hace 52 días. Creo que el equipo de React encontrará que esto solo empuja el trabajo al equipo de Facebook y a todos los equipos de bibliotecas internas y externas para mitigarlo. en lugar de).

No entiendo a qué te refieres. No dije en ninguna parte que IE11 estaba "obsoleto".

Mi publicación solo dice que es posible que necesitemos más polyfills que ahora para navegadores como IE11. React ya requiere algunos polyfills en IE11. No digo que queramos romperlo, todavía tiene muchos usuarios, pero deberá incluir más polyfills si quiere que funcione. Eso me parece completamente justo.

Además, no podemos "empujar el trabajo" a otros equipos en Facebook. Si rompemos algo, depende de nosotros arreglarlo. Esta es la razón por la que nos preocupamos tanto por las estrategias de migración; por lo general, tenemos que ejecutarlas nosotros mismos.

Re: el resto de su comentario: absolutamente no hacemos cambios importantes porque sí. De hecho, estamos tratando muy, muy duro de evitar romper los cambios. Hay muchas partes de React que son complicadas y difíciles de mantener, pero las mantenemos por la única razón de que estamos tratando de admitir las API heredadas, incluso si se han marcado explícitamente como inestables. Sin embargo, en algún momento el peso de los problemas se acumula y necesitamos hacer borrón y cuenta nueva para avanzar y solucionarlos. Los problemas en mi publicación OP son exactamente ese tipo de problemas. No valdrían la pena hacer un cambio radical solos. Pero combinados, creemos que valen la pena el esfuerzo.

No entiendo por qué la gente es tan negativa con esto. ¿Simplemente no actualice hasta que sus dependencias lo hagan?

¿El problema de la palabra clave para class frente a className y for frente a htmlFor no es algo que el compilador jsx pueda manejar para anular las palabras reservadas?

Realmente solo me preocuparía si los cambios son lo suficientemente grandes como para que los resultados de la búsqueda den respuestas obsoletas ... Como el dolor angular 2+ introducido al buscar en Google "angular -angularjs -angular1.x", etc.

¡Aparte de eso, doy la bienvenida a todos los cambios!

@gaearon

Tu dijiste

"Es posible que debamos eliminar la compatibilidad con algunos navegadores más antiguos"

Fue la parte de compatibilidad de caída con la que tuve un problema, no la siguiente parte de relleno polivinílico. Volver a la edad oscura era mi preocupación.

Respecto al proceso. ¿No es este tipo de 'problema' para lo que se diseñó el proceso RFC?

Fue la parte de compatibilidad de caída con la que tuve un problema, no la siguiente parte de relleno polivinílico. Volver a la edad oscura era mi preocupación.

Estaba hablando de IE10 y anteriores. Señalé específicamente que queremos seguir admitiendo IE11; creo que representa aproximadamente el 3 % de nuestro tráfico, que es mucho más que el límite del 1 % que consideramos demasiado antiguo.

Respecto al proceso. ¿No es este tipo de 'problema' para lo que se diseñó el proceso RFC?

Publicaremos RFC cuando las cosas estén más desarrolladas. Mucho de esto requiere exploración, experimentación y pruebas reales para determinar qué podemos y qué no podemos hacer, y qué estrategias de migración podríamos usar. No tenemos suficientes detalles en este momento para siquiera comenzar a pensar en los RFC (que deberían incluir una estrategia de migración integral).

¡Muy bien, gracias por la aclaración!

@gaearon

Es plausible que nos deshagamos de los eventos sintéticos por completo.

¿Cómo funcionaría eso con event.currentTarget apuntando al elemento en el que está conectado el detector de eventos, que en el caso nativo siempre significa document , o la raíz de React una vez que React cambia a eso?

React no es solo establecer propiedades

(...)

Mi punto aquí es que si React usa propiedades o atributos internamente es un detalle de implementación

¿Por qué es este un detalle de implementación cuando puede influir en lo que sucede en el DOM? A menos que eso se refiera solo a propiedades que de alguna manera se reflejan en atributos (y viceversa) como class / className .

Siento que la confusión en torno al tratamiento de class / className está relacionada con el hecho de que si React usa una propiedad o un atributo se considera un detalle de implementación. Tengo experiencia en Angular y cuando comencé a usar React fue el problema más grande para mí: en Angular, la separación entre atributos, propiedades y controladores de eventos es clara directamente desde la sintaxis y estaba confundido si React establece accesorios en elementos DOM como propiedades o atributos.

¿Cómo funcionaría eso con event.currentTarget apuntando al elemento en el que se adjunta el detector de eventos, que en el caso nativo siempre significa documento, o la raíz de React una vez que React cambia a eso?

no lo sé todavía :-) Veremos qué podemos hacer. Es muy posible que algunas de estas cosas no funcionen o resulten de manera diferente. Este plan es solo un bosquejo aproximado de las cosas que planeamos investigar y la visión unificadora para ellas.

¿Por qué es este un detalle de implementación cuando puede influir en lo que sucede en el DOM? A menos que eso se refiera solo a propiedades que de alguna manera se reflejan en atributos (y viceversa) como class/className.

Para la mayoría de ellos, no hay una diferencia observable desde la perspectiva del usuario sobre cuál usar. Creo que la mayoría de ellos se reflejan (aunque tal vez me equivoque).

Tengo experiencia en Angular y cuando comencé a usar React, la mayor trampa para mí: en Angular, la separación entre atributos, propiedades y controladores de eventos es clara directamente desde la sintaxis y estaba confundido sobre si React establece los accesorios en los elementos DOM como propiedades. o atributos.

Aprecio tu perspectiva. Sin embargo, en la práctica, esta diferencia a menudo es irrelevante para la mayoría de los elementos DOM y es discutible que aprender los entresijos de cuál usar, y tener que pensar siempre en ello, sea realmente valioso para el desarrollo diario de productos. Creo que el grado en que la gente los confunde habla del hecho de que en realidad no es tan relevante para ellos.

( Hay casos en los que se vuelve mucho más relevante, como con elementos personalizados. Pero incluso allí, admitir ambos por igual es tan confuso porque tienes que elegir cuál usar. Esto se ha debatido en otra parte, así que me gustaría evitar saltar en este debate nuevamente: tenemos propuestas de personas como @robdodson y las analizaremos).

@Daniel15
Sin las políticas mencionadas (que no creo que se mencionen en ningún otro lugar), el contenedor de objetos adicional no lo hace más seguro de ninguna manera.
Creo que el usuario está lo suficientemente advertido sobre el uso peligroso a través dangerouslySetInnerHTML . Ese es el punto en el que el usuario se ve obligado a revisar los documentos, considerar las implicaciones y tomar la decisión.
La necesidad de envolver la cadena (posiblemente no desinfectada) en un objeto/función, no hará que reconsidere o desinfecte el valor envuelto.
Si funcionara de esa manera, entonces quizás { __html } no sea lo suficientemente complicado y [{ _html: { __html }] lo haría aún más seguro. ¿Cuántas veces tenemos que decir que algo es peligroso para que sea seguro? ?

Con la información que proporcionó, entiendo el razonamiento, pero creo que actualmente no se aplica a nadie fuera de Facebook, porque no tenemos ni idea sobre la regla " { __html } representa html desinfectado".
Siempre pensé que es solo otra obstrucción en la API. Gracias por tomarse el tiempo y arrojar algo de luz sobre esto, tiene más sentido ahora.

No se trata solo de hacerlo más complejo, se trata de evitar que los datos no desinfectados se usen accidentalmente.

Me encanta la forma en que reacciona es tan obstinada por la comunidad. Felicitaciones por escucharlo todo y aprovecharlo al máximo.

Me encanta cómo todos piensan que los cambios que vienen aquí o que llegaron a React en las últimas versiones fueron 'rompientes'. Esas personas claramente no experimentaron Angular 2> 3> 4 veces.

Me encantan los cambios. Personalmente, no me importa className y desestructurar class podría convertirse en una molestia. Pero me encantaría ver qué se les ocurrirá.

Me gustaría pedir mantener esta discusión en el tema. Si encuentra útil o no contaminar HTML peligroso es interesante pero no está relacionado con el problema.

amo reaccionar

Esta es una oportunidad perfecta para ayudar a los nuevos desarrolladores a sentirse bienvenidos. Estoy muy contento de que esto esté sucediendo.

Permitir que las personas usen class no tiene efectos negativos, excepto que no funciona con la desestructuración y el costo de migración.

@gaearon Agregando 2c, pero esos dos negativos parecen tan grandes o más grandes que el negativo actual (un pequeño costo único de aprender clase => className vs siempre evitar la desestructuración + costo de migración a nivel de ecosistema).

reacciona :corazon:

haciéndose eco de @natew arriba:

@gaearon Agregando 2c, pero esos dos negativos parecen tan grandes o más grandes que el negativo actual (un pequeño costo único de aprender clase => className vs siempre evitar la desestructuración + costo de migración a nivel de ecosistema).

De todos modos, ¿cuál es la motivación detrás de cambiar de className a class ?
Por lo que puedo deducir, su comentario se reduce a dos argumentos (corríjame si me equivoco):

más cerca conceptualmente de lo que la mayoría de la gente espera

Ok, pero agregar Name es el más pequeño de los obstáculos. Aprender a usar className fue la parte más simple de aprender React. Es una pequeña peculiaridad que no tiene inconvenientes; de hecho, resuelve un problema con cuatro caracteres. Y tiene una sobrecarga cognitiva mucho menor que cualquiera de las alternativas de desestructuración proporcionadas.
Imagine enseñarle a alguien a diseñar su primer componente React con

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

Mi cabeza de novato habría explotado.
Creo que al interactuar con una API, las personas esperan que la API brinde soluciones. ClassName es una solución integrada. La clase es un problema incorporado.

menos escribir

Bruh, son cuatro caracteres 8^). Además, incluso si desestructuramos class con mucha menos frecuencia de lo que usamos actualmente className , es mucho más escribir cuando lo hacemos. Así que habré escrito 4 caracteres menos 12 veces pero he agregado 50 caracteres más cada una de las veces que describo class ? Esto es una tontería.

¿Hay alguna otra razón de peso para este cambio que me haya perdido?
¿Es la motivación algún tipo de preocupación sobre la conformidad con los atributos/propiedades del DOM?
Eso me parece un argumento demasiado académico. La mayoría de las personas no son muy conscientes de estos detalles de implementación y no creo que deban serlo.

¿Es que si se lanza hoy, React permitiría class en lugar de cambiar a className?
Creo que eso es irrelevante.
React no era de código abierto hoy y si fuera o fuera de código abierto dentro de un año en el futuro, se podría tomar un conjunto diferente de decisiones en ese momento.
A veces es mejor ceñirse a la consistencia que tratar de eliminar cada arruga.

Y si React hubiera estado usando la clase desde el principio, nos habríamos acostumbrado a desestructurar la clase y reasignarla a className, pero cualquiera que viniera con un PR para cambiar class _to_ className sería aclamado como un salvador.

Por último, solo quiero decir que no esperaba que esto me molestara tanto, así que me disculpo si algo me pareció grosero, insultante o acusatorio. Estoy agradecido por todo el trabajo que haces en React y por todo el conocimiento que compartes en Twitter. He usado tus tweets para defender algunas respuestas que he dado en entrevistas.

Rezo a dan.church para que cambie de opinión.

Estoy muy contento de que React se pueda actualizar continuamente. Como desarrollador del uso de React, no quiero que vue lo supere. Pero el proceso de className-> class debe ser doloroso.

No estoy en contra del cambio de nombre de className -> class para copiar y pegar, pero no hay una motivación clara para ello a partir de ahora. className existe en el DOM mientras que hay nombres de accesorios reservados que surgen de la nada como htmlFor . Siento que esos deberían tener prioridad cuando se trata de cambiar el nombre y eso probablemente sea un cambio menos generalizado que también puede servir como prueba.

@sonhanguyen htmlFor también es el nombre oficial de la API web: https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor

@allan2coder en lugar de envolverlo en una matriz, envuélvalo en <React.Fragment> o <> .

@allan2coder Además, mantengamos este hilo en el tema, puede hacer preguntas presentando un problema por separado si lo desea.

Me gustaría llamar la atención sobre patch-package que es un paquete que hace que sea bastante fácil parchear sus dependencias (por ejemplo, para que dejen de usar API de React no compatibles). Es cierto que esto es más útil para el código de la aplicación que para el código de la biblioteca, pero creo que debería ayudar a abordar algunas de las preocupaciones de @philipwhiuk .

Espero.

  • Migre de onChange a onInput y no lo rellene para componentes no controlados.

Para las palabras anteriores, tengo curiosidad, ¿se usará el evento onChange cerca del evento nativo o no se usará en el futuro?

@MuYunyun

Según la redacción, no planean mantener el comportamiento actual de onChange. No tendría mucho sentido. Reaccionar como otras bibliotecas modernas no será una capa de compatibilidad del navegador, ni debería serlo.

El onChange actual emula input + algunos otros casos. No tiene ningún sentido considerando que ya existe un evento de cambio en el DOM y no tiene la misma semántica: https://developer.mozilla.org/en-US/docs/Web/Events/change

@jxub

Un poco exagerado, pero es un poco triste que nadie (que yo sepa) tuvo la idea de hacer un transformador html/css/svg -> jsx para facilitar las migraciones a React con tantos cambios triviales para asignar atributos HTML a Reaccionar accesorios. Tantas horas-hombre desperdiciadas realizando principalmente búsqueda y reemplazo :(

No sé acerca de otros editores, pero IntelliJ IDEA (y WebStorm, PhpStorm, etc.) hace esta transformación cuando pega un código HTML en JS.

Un poco exagerado, pero es un poco triste que nadie (que yo sepa) tuvo la idea de hacer un transformador html/css/svg -> jsx para facilitar las migraciones a React con tantos cambios triviales para asignar atributos HTML a Reaccionar accesorios. Tantas horas-hombre desperdiciadas realizando principalmente búsqueda y reemplazo :(

En realidad existe, pero es bastante antiguo y no es del todo correcto: https://magic.reactjs.net/htmltojsx.htm

Debemos revivir ese esfuerzo. Si desea ayudar, hágalo: https://github.com/reactjs/reactjs.org/issues/484. Hasta el momento nadie se ofreció a ayudar y dio seguimiento.

En realidad existe, pero es bastante antiguo y no es del todo correcto: https://magic.reactjs.net/htmltojsx.htm

Lo he usado muchas veces antes: es muy común usarlo cuando se subcontratan ciertos componentes a personas que conocen HTML/CSS pero no JavaScript.

Entonces, solo brindo comentarios de que esta es una herramienta útil que la gente usa en la práctica. También hay otros convertidores en línea.

Un problema con este enfoque es que es solo unidireccional (solo migrar _para_ reaccionar). Sin embargo, ese problema no es especial para React.

Espero que haga las cosas mucho más fáciles...

Un problema con este enfoque es que es solo unidireccional (solo migrar para reaccionar). Sin embargo, ese problema no es especial para React.

¿Por qué? Debería ser aún más fácil al revés: simplemente ejecute ReactDOMServer.renderToString .

Esperando pacientemente el lanzamiento

@gaearon

¿Por qué? Debería ser aún más fácil al revés: simplemente ejecute ReactDOMServer.renderToString.

Ok, entonces, para el contexto, el problema discutido es: quiero que las personas que escriben html/css y no conocen JavaScript lo suficientemente bien como para trabajar en el código JS puedan trabajar en el marcado/estilo/diseño de los componentes.

Una forma de hacer esto ahora mismo es hacer que lo desarrollen en html/css y usen htmltojsx. Eso funciona bastante bien para mí.

El problema es que ahora tengo que mantener cada cambio de marcado/estilo/diseño yo mismo en React.

Si llamo a ReactDOMServer.renderToString , de hecho obtendría HTML estático, pero a ese HTML le faltaría todo el código del componente real, por lo que no es factible dárselo a las personas de UI y usar su salida, ya que tendría que volver a escribir todo mi lógica

Cosas como react-sketchapp son una buena forma de abordar el problema, pero espero un enfoque más genérico que me permita hacer esto mientras uso html/css normal. Por ejemplo, a través de alguna forma de metadatos y manteniendo los ID de reacción en los elementos.

Entiendo totalmente que esto no está dentro del alcance del núcleo de ReactDOM, pero definitivamente está en su dominio y es un problema interesante.

Esto no es una prioridad alta; principalmente quería explicar por qué htmltojsx es útil para algunos de nosotros, incluso fuera del contexto de una migración :)

Quiero que las personas que escriben html/css y no conocen JavaScript lo suficientemente bien como para trabajar en el código JS puedan trabajar en el marcado/estilo/diseño de los componentes.

¿Qué tan grande es este problema y qué tan difícil sería enseñarles un poco de JSX? Los cambios deben ser revisados ​​por un ingeniero experto en React de todos modos.

Lo siento si esto se desvía demasiado del tema, pero creo que solo HTML/CSS no es suficiente hoy en día.

( @gaearon siéntase libre de ocultar esto si se vuelve ruidoso ya que es una respuesta sobre el comentario de OT anterior que ya es leve)

¿Qué tan grande es este problema y qué tan difícil sería enseñarles un poco de JSX? Los cambios deben ser revisados ​​por un ingeniero experto en React de todos modos.

Bueno, requeriría lo siguiente:

  • Solo trabaje con contratistas que estén familiarizados con su pila React actual. Es mucho más difícil encontrar personas que aprendan componentes con estilo
  • Instale Node (npm), su pila (React, webpack, etc.) y todo lo demás necesario para ejecutarlo en cada una de las computadoras de las personas de UI y mantenerlo actualizado.
  • Enséñeles algo de programación básica y JavaScript, aprendiendo a trabajar con las herramientas de desarrollo, errores de la consola, etc.
  • Enséñeles React, cuál es su sintaxis, cosas como className , qué significa key , etc.
  • Solo trabaje con contratistas y autónomos que estén dispuestos a trabajar de esa manera en lugar de producir HTML/CSS. Esto generalmente también encarece las cosas.

Ahora, como se mencionó anteriormente, cosas como react-skeptchapp son una forma útil de hacer que esto sea más accesible y fácil para las personas de UI, pero aún requiere que aprendan mucho.

Entiendo perfectamente por qué preguntas esto y no estoy seguro de que sea un problema común (sospecho que lo es). Independientemente, no creo que esté al alcance del futuro del núcleo de ReactDOM.

Esto está bastante fuera de tema :-) Continuemos esta discusión en Twitter o en otro lugar.

"El comportamiento para el que ves que se usa una herramienta es un comportamiento que la herramienta fomenta"
~ Gary Bernhardt

La forma en que se usa React, ya que la mayor parte no es parte de la API de React, da como resultado una gran cantidad de dificultades que generan discusiones como esta en las que todos están confundidos y frustrados. ¿Usar una palabra clave reservada como class es malo debido a javascript, html o reaccionar en sí mismo?

Volviendo a los cambios realizados en 16.3 (si no recuerdo mal), la biblioteca ahora se comportaría de manera diferente al aceptar cualquier atributo pasado a los elementos html nativos representados por el vdom, recuerdo claramente que la mayor parte de mi base de código ahora estaba plagada de errores porque del comportamiento que tuvimos implementando este patrón claramente malo

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

Así que debo decir que estoy bastante decepcionado de que Dan sugiera que sigamos difundiendo este terrible código en todas las bases de código.

En primer lugar, no hay garantías en el contenido de props , pero la primera vez, los elementos html nativos casi siempre no harán lo que se espera de ellos si le pasa los accesorios incorrectos, sin embargo, al mismo tiempo se considera seguro propagar accesorios de padres a componentes secundarios, pero en realidad esto es terriblemente vago

<Child {...props} />

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

A veces, ni siquiera sabe lo que está renderizando y este problema se vuelve aún más difícil de manejar. También es extremadamente difícil verificar este tipo de componentes utilizando sistemas de tipos porque eso significaría que la mayoría de los componentes deben implementar una serie de interfaces aleatorias que deben compartir entre sí, es un agujero muy profundo para entrar.

Si se hace una reescritura para reaccionar para arreglar esto, esperaría que los diseñadores detrás de esto se den cuenta del daño que estos malos patrones causan a la base de código en lugar de duplicar las malas decisiones.

Debemos recordar que jsx está construido sobre javascript, y usar las "idiosincrasias" de javascript como excusas para entrar en conflicto deliberadamente con el idioma en el uso de palabras clave es un mal primer paso para arreglar la API, sugeriría que en lugar de comenzar una guerra contra el lenguaje te alejarías de él por completo

@gaearon ¡Cuánto tiempo! :) (ps. Lo siento por tl; dr adelante)

De todos modos, solo quería dar una idea de lo que he aprendido de mis propias aventuras. Creé mi propio derivado de React "mínimo" que ahora uso para aplicaciones críticas de rendimiento/características. Inicialmente fue solo un experimento secundario divertido, pero observé mejoras de rendimiento de más del +300 % en casos del mundo real para la renderización/actualización/eliminación inicial, incluidos muchos otros beneficios. Eso es sin usar un controlador de eventos agrupados también.

IIRC, una gran parte de esto proviene simplemente de mi propia biblioteca sin pasar por toda la lógica de React-props y simplemente alimentando atributos directamente a setAttribute, estilos directamente a style.setProperty, oyentes directamente a addEventListener, y así sucesivamente. Entonces, la interfaz básica del elemento DOM se ve así `{attributes: {}, style: {}, listeners: {}, className: "", ...}, es más detallado pero la interfaz ahora es pequeña y trivial de implementar y es extremadamente rápido. Esto es probablemente demasiado extremo para ti, pero me ha servido muy, muy bien.

Algo que también he estado haciendo es eliminar CSS por completo, todos los estilos están en línea. Es mucho más rápido de lo que cabría esperar y viene con muchos beneficios prácticos agradables, también evita el costo del análisis CSS inicial del navegador (que es sorprendentemente costoso) y la coincidencia de selectores que recupera la mayor parte de los gastos generales. Puedo lograr fácilmente 60 FPS estables y mucho más en mi computadora portátil con poca potencia incluso para jerarquías complejas (sin podar árboles).

Me imagino que la mayor parte de eso no es realmente útil para ti, pero tal vez haya algo interesante allí. De todos modos, mi principal queja con HTML+React es que los componentes de usuario de React no exponen ninguna interfaz para el diseño/posicionamiento (y probablemente hasta cierto punto también los eventos) sin recurrir a CSS. En pocas palabras, si creo un ButtonComponent y luego lo uso, por defecto no se puede colocar ni integrar en un diseño sin; implementando una lógica de propósito especial dentro de él, envolviéndolo en un elemento ficticio que se puede colocar o exponiendo un accesorio de estilo que se fusiona con los estilos utilizados para el elemento raíz de ButtonComponent. Ninguno de ellos es perfecto, y fusionar estilos tal cual es peligroso, ya que es fácil incluir estilos que no deberías. Esencialmente, el problema es que en los límites de los componentes, un subconjunto de las propiedades disponibles debe ser público (posicionamiento/diseño) y algo interno (estilo visual).

Otra cosa que hago es la separación entre componentes y contenido/hijos. Por ejemplo, los componentes DOM no toman una lista de elementos secundarios, sino que aceptan una instancia de contenido. La instancia de contenido implementa la lógica de reconciliación y la representación de elementos secundarios, lo que significa que puede tener diferentes implementaciones para diferentes propósitos. Los casos de uso más obvios son; en su mayoría jerarquías estáticas frente a niños generados dinámicamente. Por lo tanto, las jerarquías estáticas que constituyen la mayoría se pueden implementar utilizando una lógica más rápida y simple, mientras que los elementos secundarios generados dinámicamente pueden tener estrategias configurables. También abre la posibilidad de tener "componentes de contenido" que podrían usarse para administrar de manera inteligente, por ejemplo, diseños de flexbox sin direccionamientos indirectos innecesarios.

Relacionado con eso y algo que creo que React se equivoca son los niños, aún no he llegado a una conclusión o solución específica. Pero creo firmemente que hay un problema fundamental en React en el sentido de que no se pueden hacer burbujas de accesorios desde la raíz hasta un punto arbitrario en la jerarquía sin volver a renderizar cada elemento entre esos dos puntos y la poda efectiva también suele ser problemática. El rendimiento es en su mayoría "suficientemente bueno" y la complejidad adicional de administrar esto en React podría no hacer que valga la pena resolverlo. Pero en mis experimentos hasta ahora he podido reducir los costos completos de actualización de raíz a meras fracciones con cantidades muy pequeñas de código trivial, pero mi intuición dice que no es muy compatible con la filosofía de React o su modelo de niños simplista.

Algo que definitivamente no es para ti, pero una gran característica de mi biblioteca es que básicamente solo proporciona un "elemento DOM básico" mínimo para propósitos generales. La idea es que puede extender/reemplazar e implementar de forma trivial sus propios comportamientos específicos de bajo nivel si está desarrollando un proyecto grande con requisitos/circunstancias específicos de forma muy económica y sin recurrir a "trucos", por ejemplo, si está muy tocado -orientado, quiere hacer un manejo de estilo especial, etc. También significa que las diferentes versiones son compatibles y se pueden ejecutar en paralelo siempre que la ABI sea la misma (un cambio debe ser extremadamente raro y muy simple de arreglar ). Esto también significa que puede ser bastante obstinado en la interfaz del elemento DOM sin tener que abarcarlo todo y tratar de resolver el problema de todos.

De todos modos, tal vez en su mayoría solo divague y probablemente no esté transmitiendo muy bien la mayoría de los conceptos, pero tal vez haya algo de información interesante para usted de alguien que fue en la dirección opuesta. La mayor parte probablemente no sea relevante para usted simplemente porque está apuntando a la "simplicidad", pero quién sabe :)

Además, antes de que lo olvide, es posible que le interese mi función objectKeyValueReconcile , específicamente optimizada para ser extremadamente rápida para comparar accesorios anteriores/siguientes para escenarios similares a React. Para mí, es responsable de ganancias de rendimiento bastante significativas en el mundo real.

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

En mi humilde opinión, dejaría caer la idea de "clase". JSX eventualmente morirá.

¿Cuáles son los pensamientos de agregar soporte para DOM/eventos de ventana no basados ​​en elementos para React DOM? Con la posible eliminación de eventos sintéticos, sospecho que todavía habría alguna forma de recopilación/actualización/procesamiento por lotes de eventos. Los eventos de pulsación de tecla, cambio de tamaño y desplazamiento de ventana son escenarios comunes que vienen a la mente, pero posiblemente ser capaz de admitir la mayoría o toda la lista en https://developer.mozilla.org/en-US/docs/Web/Events sería ser beneficioso detrás de la misma abstracción.

Esto también se discute en el número abierto más antiguo #285 😄.

@gaearon

El efecto práctico de className -> class será:

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

se convertirá

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

Este cambio causará bastante dolor mientras que los beneficios son completamente académicos . Hemos visto a otras comunidades hacer cosas similares, por ejemplo, considere que python3 se lanzó por primera vez hace una década y todavía estamos discutiendo al respecto. Una parte considerable de la comunidad no ha hecho la transición y nunca lo hará. Por favor reconsidera.

@kans

O esto:

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

Eso es de una complejidad similar a la función original.

Me gustó className porque class es una palabra clave en js, pero no creo que sea tan importante de ninguna manera. Prefiero peinarme con algo glamoroso, así que esto no es algo que me afecte. ¿Quizás he usado className un par de docenas de veces en los últimos años? Casi nunca.

Aunque un pensamiento que se me ocurrió a favor de class es que la mayoría de las personas que realmente usan className están usando css, y esperan el modelo html/css de class . El propósito abrumadoramente principal de este accesorio realmente es simplemente vincularse con el código css, ¿verdad? Entonces, ¿por qué no simplemente llamarlo clase como espera un usuario de html/css?

En mi opinión, fuera del código del sistema de diseño, el desarrollo de React realmente idiomático normalmente no usaría className o class de todos modos. Cuando necesito usar clases para css, en su mayoría está aislado en algunos componentes pequeños de la interfaz de usuario. Casi todo lo que se usa en la capa de aplicación es de nivel superior (como, por ejemplo, <Columns verticalAlign="center"> o <BodyText /> ).

Así que supongo que me pregunto si cambiar el nombre de className a class hace que sea más fácil para el tipo de personas que usan el accesorio de todos modos (más fácil entrar en el desarrollo de React, cambiar de contexto, no enojarse , etc), ¿por qué no cambiarle el nombre?

Reduzca el tamaño del paquete, por favor.

Dado que esta es una actualización grande y de última hora, ¡quizás también podríamos corregir el nombre del ciclo de vida de React!

es decir shouldComponentUpdate => shouldUpdate , etc. Este nombre es más que tonto.

@AlexGalays

Dado que esta es una actualización grande y de última hora, ¡quizás también podríamos corregir el nombre del ciclo de vida de React!

es decir, shouldComponentUpdate => shouldUpdate, etc. Esta denominación es más que tonta.

Los nombres de enlace de ciclo de vida más largos son menos ambiguos cuando se buscan. Los nombres más cortos son demasiado genéricos y dependen del contexto en el que se encuentran, por lo que coincidentemente pueden coincidir con otra cosa en una base de código grande (coincidencia de falso positivo).

Los métodos de ciclo de vida son parte del núcleo de React, y este problema se trata únicamente de react-dom.

@ljharb
¡Uy, de verdad!

@sompylasar
Lo sentimos, simplemente no es una buena razón (juego de palabras, ReasonReact corrigió los nombres de los métodos :)). No prefijamos todos nuestros módulos por sus nombres de paquete también y los encontramos bien. De todos modos, voy a dejar de hablar de esto ya que react-core está fuera del alcance de este problema.

Me encantaría ver estos cambios.
Espero que se implementen teniendo en cuenta la interoperabilidad de elementos personalizados.

Me pregunto si vale la pena mover algunas de las discusiones a hilos separados en el foro (https://discuss.reactjs.org). Dado que los problemas de GitHub no están encadenados como las publicaciones del foro, es complicado discutir varias cosas diferentes en el mismo problema.

Me parece interesante el cambio de className -> class 😺

Ver, 2019 Reaccionar proyectos

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

Esto lo veo venir seguro.

Me encanta poder copiar y pegar HTML y no tener que cambiar className pero al mismo tiempo veo los problemas que podría traer la palabra clave reservada class .

En este punto, preferiría quedarme con className a menos que tenga una gran preocupación de ingeniería al respecto (no una preferencia personal)

Pero esa es solo mi opinión pragmática.

Si bien entiendo la fricción adicional de no poder destruir el identificador class , siento que demasiadas personas en este hilo sobrestiman la cantidad de veces que necesitan recibir el nombre de la clase como accesorio.

Pasar className a un componente React (que no es solo un elemento DOM) significa que está creando bloques de construcción bastante pequeños sin proporcionar nuevas abstracciones o que ese componente expone algunos de sus detalles de implementación. En el primer caso (por ejemplo, el componente <Button /> ), probablemente desee seguir el ejemplo de @gaearon y reenviar el "resto" de accesorios al elemento DOM también. En el segundo caso, tal vez la fricción adicional lo obligue a evitar hacer la cosa y encontrar una mejor solución.

Desde mi humilde experiencia, tuve que copiar y pegar HTML a JSX (y reemplazar class con className ) más veces de las que recuerdo haber creado un componente que recibe className .

Difundir todos los accesorios a un HTML es un patrón anti. Si alguien en el futuro incluye una propiedad adicional que coincide con un atributo HTML, cambiará inesperadamente el comportamiento. Si IE agrega un nuevo atributo, estás perdido.

@philipwhiuk si solo distribuye los accesorios que no usa, no habrá ningún problema de comportamiento.

@j-f1

si solo repartes los accesorios que no usas no habrá ningún problema de comportamiento.

Realmente no. Si agrega una nueva opción a la API de su componente, esta opción deja de pasar al nodo DOM subyacente. Alguien puede depender de que ese atributo exacto se establezca en el elemento y luego rompa a esa persona. Difundir todos los accesorios no utilizados a cualquier cosa debajo significa que cualquier adición a la API de su componente es un cambio importante.

Por cierto, utilicé un ejemplo aleatorio en el que deconstruyes el valor de class pero no te quedas sin ese detalle.

Muchos de ustedes (sí, lo hacen) deconstruyen casi todos los valores de props y state en lugar de usar la notación de puntos por otras razones que no sean evitar escribir texto adicional.

Es por eso que estoy haciendo énfasis en la situación, pero no se desvíe y se centre en difundir accesorios o cualquier otro tema secundario sobre el que pueda hablar.

Si eres un poco más pragmático, hablarías sobre las implicaciones técnicas en lugar de tus preferencias personales, pero no veo a nadie diciendo nada sobre las implicaciones técnicas de className .

Otra cosa a la que debe prestar atención es que está haciendo que los colaboradores principales se centren en algo que es una cuestión de preferencias personales (pruebe que estoy equivocado, solo porque quiero que piense en ello de manera pragmática)

Su tiempo, esfuerzo y dinero (de la empresa) son limitados, así que mejor si la comunidad entiende que hay mejores cosas en las que centrar nuestra atención y si alguien del equipo central dedica una hora a algo en lo que preferimos que lo usen. la próxima gran cosa para React, no hay código de refactorización para tal cambio.

Pero de nuevo, mi opinión pragmática.

Hablando de polyfills, no creo que react deba intentar detectar si el usuario especificó polyfills "buenos".
(por ejemplo hasBadMapPolyfill en el código)
React no debe hacerse responsable de todos los errores aleatorios que se pueden cometer en un proyecto de programación.

@AlexGalays React se basa en el uso de una implementación de mapa con la semántica correcta. Si los usuarios usan un polyfill que no cumple con los requisitos, su aplicación puede fallar de manera inesperada y confusa, por lo que es útil advertir con anticipación en ese caso.

Esto solo se hace en la compilación de desarrollo también, por lo que no hay gastos generales para esto en producción.

Me encanta este React Fire y usted continuaría trabajando en esto, ya que parece un paso más interesante para modernizar ReactDOM.

¿Sería posible que reaccionar fuego no vuelva a vincular los controladores de eventos?

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

No creo que nadie realmente quiera que el controlador de eventos se rebote. Y en los raros casos en los que lo haría, podría vincularlo manualmente

@cullophid

¿Sería posible que reaccionar fuego no vuelva a vincular los controladores de eventos?

Puede vincular el método a la clase una vez utilizando los enlaces automáticos de la función de flecha o vinculando la función en su constructor. Si hay parámetros únicos que desea encadenar al evento, puede memorizar los controladores de eventos o adjuntar atributos DOM a los nodos y acceder a ellos a través event.currentTarget .

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

Otro beneficio de simplificar el sistema de eventos (¿podemos volver a los eventos DOM sin procesar sin ninguna agrupación como lo hacen TODOS los marcos? :)) es que también es más fácil escribir estáticamente.

¡Parece un gran plan! Sería muy bueno tener soporte para IE 11 (incluso si eso significa enviar nuestros propios polyfills, lo cual está totalmente bien). Como alguien que trabaja con clientes gubernamentales, no se sabe cuándo dejarán de usar IE 11 :(

@MatthewHerbst mismo barco, nuestros clientes usan IE 11 y tenemos suficiente tráfico 😢

Solo quería intervenir para decir que todo esto es súper emocionante. Lo único que leí que me preocupó fue:

es posible que no intentemos suavizar algunas de las diferencias existentes entre los navegadores

En este momento, me encanta saber que el sistema de eventos de React "simplemente funcionará" en cualquier navegador compatible con React. Me temo que este cambio significará que será responsabilidad de la aplicación dar cuenta de los problemas entre navegadores. Esto probablemente introduciría muchos errores difíciles de rastrear. ...al menos lo haría para mis aplicaciones. :)

De todos modos, gracias como siempre por la gran biblioteca.

@kentcdodds había mencionado la integración de JSX 2.0 como una idea posible. Estaba leyendo la Estrategia y no vi nada que pareciera relacionado con eso. Me preguntaba si eso estaba en el aire o algo que se retrasará para el futuro.

¡Que muera el IE! No es compatible con navegadores absolutamente obsoletos. No hay razón, incluso para las empresas restrictivas, para no cambiar a un navegador actualizado. Verá ese IE11 en sus estadísticas hasta que usted y la web dejen de admitirlo.

@hbroer ¿Software heredado?

@hbroer nadie se queda en un navegador antiguo porque sus sitios aún funcionan, lo hacen porque no tienen otra opción o no saben cómo actualizar. Romper un sitio para estos usuarios es extremadamente hostil y los deja no con un navegador actualizado, sino sin nada.

  • "no sé cómo actualizar" - no es problema nuestro, pero podemos poner mensajes "instalar un nuevo navegador" con una lista de navegadores y tal vez con texto de ayuda y número de teléfono de la línea directa de Microsoft ^^
  • "no tengo opción" - Correcto, pero la organización tiene que actualizar su entorno. Si sus herramientas no funcionan, lo harán.

Odio codificar para el pasado y no puedo usar el beneficio de la nueva tecnología, porque el 90 % de los programadores aún son compatibles con los navegadores de mierda del 15 % de los consumidores más pobres que vivían en el siglo pasado. ^^ No quiero tener este "oh, qué pasa con este Internet Explorer 6 nerds, tenemos que apoyar ese 15%" nuevamente durante los próximos 10 años.

Por cierto M$ costuras para traer Edge para Windows 7 y 8 con su cambio a webkit.

@hbroer todo es problema nuestro si impacta a los usuarios. Tener algo de empatía por otros humanos.

(Por separado, M$ es una referencia bastante juvenil y muy anticuada de finales de los 90 que es posible que desee eliminar; me complace eliminar esto a un lado si lo hace)

Ya veo, aquí hay muchos M$ fanboiz. :D Realmente me preocupo por los humanos, pero no por las organizaciones que bloquean el progreso de la tecnología, o los programadores que pretenden tener que soportar esa vieja mierda durante años. No tengo ningún problema con un paquete adicional que hace que una biblioteca sea "compatible con basura antigua". Pero una biblioteca en 2019 debe codificarse con tecnología >=2019 en mente, y no tecnología <=2013. Ya es bastante malo tener que soportar ese (oh, hagámoslo de otra manera) safari y (vieja) mierda de borde.

gota de micro

@hbroer , de hecho, el antiguo navegador de Android y el antiguo safari son más problemáticos que cualquier navegador de Microsoft. no se trata de ser un "fanboi" sino de ser profesional, y usar el termino "M$" no lo es.

Y no, no es "malo" de ninguna manera apoyar la tecnología antigua, es lo moral y ético que hay que hacer. Lo malo son los sitios web que "funcionan mejor en X", ya sea Netscape Navigator, IE 6 o la última versión de Chrome.

Ya veo, aquí hay muchos M$ fanboiz.

@hbroer Veo aquí a una persona con ataques generales ad hominem.

Pero una biblioteca en 2019 debe codificarse con tecnología >=2019 en mente, y no tecnología <=2013.

No, no debería.

Si se tomó un segundo y miró los valores predeterminados de la lista de navegadores, se sorprendería. En cambio, recurres a ataques ad hominem e insultos al nivel de la cafetería de la escuela.

Una vez que obtiene suficientes usuarios, IE11 se convierte en una parte considerable de las personas que acceden a su sitio web. En un trabajo anterior teníamos cerca de un millón de personas al mes accediendo a nuestro sitio web desde IE11.

browsers

Si quieres soporte para cosas viejas, agrega rellenos poli. No hay razón para no codificar para el futuro y el presente. La compatibilidad con tecnología antigua hace que las aplicaciones web sean más voluminosas y lentas de lo necesario.

PD Veo a una persona que no puede leer el sarcasmo y no le importan las caritas ^^

@hbroer Está mostrando que IE11 es el presente, por lo que se espera que codifiquemos para eso.

Una vez mas. Consulte el valor predeterminado en https://browserl.ist.

PD Veo a una persona que no puede leer el sarcasmo y no le importan las caritas ^^

Si no. Esta es una táctica común empleada por los trolls y los matones del patio de recreo. "¡¿Qué?! ¡No te insulté! ¡Era solo una broma!".

El 0,20% de las personas del planeta, incluso filtrado por "los que usan internet", son 6,4 millones de seres humanos. Los porcentajes son completamente irrelevantes. Código para humanos; el pasado y el futuro, y el tamaño de su paquete, no importan.

Si desea codificar para el tamaño del paquete de humanos, al igual que la compatibilidad del navegador, ciertamente importa. Los usuarios no solo esperan que las cosas funcionen, sino que también deben cargarse rápidamente.

Ahora, en 2019, usaré para nuevos proyectos css grid (que solo tiene soporte experimental en IE11), y transpilaré a ES6 y no quiero entregar polyfills para ese navegador obsoleto. Los usuarios de IE11 simplemente reciben un mensaje: actualice su navegador o use una alternativa.

Hay gente por ahí que no quiere usar java script. ¿Te preocupas por ellos? No ves a esos chicos en las estadísticas. Y tampoco estoy en estadísticas, como muchas otras personas que bloquean esas herramientas.

Echo un ojo a todos los navegadores que no estén desactualizados. Soy compatible con Edge, que tiene menos usuarios que esa basura de IE11, debido a Windows 7 (que es compatible hasta enero de 2020), y la gente moderna usa navegadores modernos. ^^

Nadie le impide usar polyfills y algo así como un paquete de compatibilidad. Pero el núcleo debe estar actualizado y no quedarse atrás solo por una pieza de un antiguo navegador de tecnología M $.

Lo que me falta en muchos marcos de JavaScript es LTS. De eso podemos hablar. Si construye una página moderna con características del presente, entonces es bueno usar un marco tecnológico actualizado. Y si está creando una aplicación web para cosas b2b que necesita la máxima estabilidad y compatibilidad, entonces puede usar una versión LTS. O usar knockout. Entonces puede apoyar a las pocas personas 100t que todavía usan Windows XP no actualizado con IE6 ^^

La compatibilidad se enumera claramente en "compensaciones" en la publicación original, por lo que tener un soporte perfecto para navegadores antiguos ya es un enfoque secundario.

Requerirán más polyfills e integración si necesita admitirlos, pero esa sería su elección . También puede crear varios paquetes para diferentes objetivos de navegador y entregar el JS más pequeño posible para cada visitante para que no afecte a toda su audiencia.

El progreso de React Fire en sí mismo parece no verse afectado, por lo que realmente no hay nada que ganar con este debate. Avancemos por favor y volvamos al tema principal.

¿Sería esta una buena oportunidad para resolver #6410? Parece similar en impacto a los cambios propuestos a onChange / onInput .

Actualización del 5 de junio de 2019

Ha sido un tiempo. Aquí hay una pequeña actualización sobre dónde estamos.

Empezamos a trabajar en Fire en diciembre. Hay algo de trabajo en progreso en https://github.com/facebook/react/pull/14382 y otros hilos. Sin embargo, a medida que comenzamos a eliminar partes del sistema de eventos que pensábamos que eran innecesarias o estaban desactualizadas, descubrimos muchos casos extremos en los que estaba siendo muy útil y evitaba errores, incluso en los navegadores modernos. Todavía queremos reducir la sobrecarga heredada, pero no está claro que estar más cerca de los eventos DOM sin procesar sea la mejor dirección en la práctica. Reducir el código de la biblioteca solo para volver a agregarlo varias veces en el código de la aplicación no es la mejor compensación. Y ni siquiera siempre es posible solucionarlo a nivel de aplicación.

Por otra parte, mientras trabajábamos en FB5 , nos dimos cuenta de que incluso cuando usamos React, hoy en día existen importantes dificultades para implementar interfaces de usuario que funcionen y se sientan bien tanto en el mouse como en los dispositivos táctiles. Incluso las cosas básicas como los botones se sienten muy diferentes con el mouse y el toque cuando usa eventos como onClick , y se vuelve aún más difícil lograr un comportamiento consistente con el desplazamiento, el enfoque, etc.

Entonces, cuando comenzamos a trabajar en Fire, pensamos que tal vez no era necesario un sistema de eventos personalizado. Pero después de crear un prototipo para eliminarlo, nos dimos cuenta de que nuestro sistema de eventos es, de hecho, nuestra mayor palanca para solucionar este conjunto de problemas .

Como resultado de esta investigación, hemos detenido temporalmente el trabajo en otros elementos que forman parte de React Fire y decidimos centrarnos primero solo en el sistema de eventos. Ese proyecto se conoció como React Flare (https://github.com/facebook/react/issues/15257). Es lo suficientemente desafiante por sí mismo y afecta a los demás elementos de esta lista, por lo que nos estamos centrando primero en él de forma aislada.

El objetivo de React Flare es facilitar la creación de interfaces de usuario que se sientan geniales en computadoras de escritorio y dispositivos móviles, con mouse y táctiles, y que sean accesibles. Incluye API declarativas para administrar interacciones como Presionar, Pasar el cursor y Foco. A diferencia del sistema de eventos React actual, el diseño de Flare no infla el paquete para los eventos que no usa, y debería permitir reducir la cantidad de código en las bibliotecas de la interfaz de usuario que se ocupan de los eventos táctiles y del mouse.

React Flare sigue siendo un experimento, pero confiamos bastante en su dirección general y planeamos que eventualmente esté disponible oficialmente en código abierto. (Por ahora, solo funciona si compila manualmente desde el maestro, y no hay garantías parciales, ya que estamos trabajando activamente en ello). Al igual que Fire, "Flare" es solo un nombre en clave; para cuando lo enviemos, tendrá denominación adecuada, documentación, etc. Tal vez react/events o algo así. También nos gustaría ofrecer eventos equivalentes en React Native eventualmente.

Una vez que hayamos terminado la implementación inicial de React Flare, volveremos a la lista de React Fire y reevaluaremos todos los demás puntos utilizando lo que hemos aprendido de ella. Todavía es probable que si Flare se hace cargo de un conjunto de eventos "más rico", podemos simplificar el manejo de eventos "básicos" en React DOM y eliminar un montón de polyfills. Gracias a todos por la discusión hasta ahora, y espero que esto sea útil.

¡Buen trabajo! Por lo tanto, el sistema de eventos sigue siendo necesario para equilibrar los eventos táctiles y del mouse, pero será liviano e independiente de React.

¿"React Flare" vendrá como parte del paquete React predeterminado o necesitará una instalación adicional considerando la cantidad de API con las que se enviará?

Nos gustaría evitar que el código no utilizado se empaquete. Entonces, la intención actual es que sea opcional por API. Tal vez puntos de entrada separados en un solo paquete.

¿Aprovechará este sistema de eventos de ratón y toque PointerEvent ? No vi una mención de este estándar web en la actualización anterior, así que solo quería llamar su atención.

Los eventos de puntero son eventos DOM que se activan para un dispositivo señalador. Están diseñados para crear un único modelo de evento DOM para manejar dispositivos de entrada señaladores, como un mouse, un lápiz óptico o un toque (como uno o más dedos). El puntero es un dispositivo independiente del hardware que puede apuntar a un conjunto específico de coordenadas de pantalla. Tener un modelo de evento único para punteros puede simplificar la creación de aplicaciones y sitios web y proporcionar una buena experiencia de usuario independientemente del hardware del usuario.

Y aquí hay un enlace directo a la compatibilidad actual del navegador .

@jonathantneal Sí, el nuevo sistema usa mucho los eventos de puntero, con respaldos para eventos de mouse/toque cuando no hay soporte para eventos de puntero.

Me preocupa que https://github.com/facebook/react/issues/11347 no se haya abordado en este problema. React falla https://custom-elements-everywhere.com.

Considere la posibilidad de usar shadow root al rediseñar el sistema de eventos: simplemente adjuntarlo a React root no resolvería la mayoría de los problemas hoy en día, solo adjuntarlo al elemento (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)

En esta actualización: https://github.com/facebook/react/issues/13525#issuecomment -499196939 @gaearon menciona:

Sin embargo, a medida que comenzamos a eliminar partes del sistema de eventos que pensábamos que eran innecesarias o estaban desactualizadas, descubrimos muchos casos extremos en los que estaba siendo muy útil y evitaba errores, incluso en los navegadores modernos.

Tenía curiosidad por saber si una lista de estos casos extremos está documentada en alguna parte.

@gaearon ahora que Flare se ha apagado (SCNR), ¿hay un plan actualizado (con respecto a la actualización del 5 de junio de 2019 ) sobre cómo proceder?

Y al igual que @trusktr , también me gustaría que se aborde el #11347 aquí.

Podrían dividirse los polyfills en otro paquete, especialmente el que no es relevante para los principales navegadores de hoja perenne.

Hola a todos, ha pasado un tiempo y hemos probado algunas de estas cosas de vez en cuando.

Permítanme darles una actualización sobre cada uno:

Todavía queremos hacer esto, pero hemos decidido "reservar" React 17 para que tenga los mínimos cambios importantes posibles para que pueda centrarse en el siguiente elemento de esta lista. Entonces este cambio esperará hasta React 18.

  • Adjunte eventos en la raíz de React en lugar del documento (https://github.com/facebook/react/issues/2043). Adjuntar controladores de eventos al documento se convierte en un problema al integrar aplicaciones React en sistemas más grandes. El editor Atom fue uno de los primeros casos que se topó con esto. Cualquier sitio web grande eventualmente desarrolla casos extremos muy complejos relacionados con stopPropagation que interactúan con código que no es de React o a través de raíces de React (https://github.com/facebook/react/issues/8693, https://github .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). También querremos adjuntar eventos con entusiasmo a cada raíz para que podamos hacer menos comprobaciones de tiempo de ejecución durante las actualizaciones.

Estamos haciendo esto en React 17. Esto resultó ser una gran cantidad de trabajo, pero afortunadamente está terminado.

  • Migre de onChange a onInput y no lo rellene para componentes no controlados (https://github.com/facebook/react/issues/9657). Consulte el problema vinculado para obtener un plan detallado. Ha sido confuso que React use un nombre de evento diferente para lo que se conoce como evento input en el DOM. Si bien generalmente evitamos hacer grandes cambios como este sin un beneficio significativo, en este caso también queremos cambiar el comportamiento para eliminar cierta complejidad que solo es necesaria para casos extremos como la mutación de entradas controladas. Por lo tanto, tiene sentido hacer estos dos cambios juntos y usarlos como una oportunidad para hacer que onInput y onChange funcionen exactamente como lo hacen los eventos DOM para los componentes no controlados.

Es probable que volvamos a esto, pero no está claro cuánto vale la pena hacer aquí. Así que esto todavía está por determinarse.

  • Simplifique drásticamente el sistema de eventos (https://github.com/facebook/react/issues/4751). El sistema de eventos actual apenas ha cambiado desde su implementación inicial en 2013. Se reutiliza en React DOM y React Native, por lo que es innecesariamente abstracto. Muchos de los polyfills que proporciona son innecesarios para los navegadores modernos y algunos de ellos crean más problemas de los que resuelven. También representa una parte significativa del tamaño del paquete React DOM. No tenemos un plan muy específico aquí, pero probablemente bifurcaremos el sistema de eventos por completo y luego veremos qué tan mínimo podemos hacerlo si nos atenemos más a lo que nos da el DOM. Es plausible que nos deshagamos de los eventos sintéticos por completo. Deberíamos dejar de burbujear eventos como eventos de medios que no burbujean en el DOM y no tienen una buena razón para burbujear. Queremos conservar algunas capacidades específicas de React, como burbujear a través de portales, pero intentaremos hacerlo por medios más simples (p. ej., reenviar el evento). Es probable que los eventos pasivos sean parte de esto.

Probamos esto a principios de 2019, y un sistema de eventos verdaderamente mínimo no funcionó muy bien en nuestras pruebas internas. Hubo bastante normalización entre navegadores que React está haciendo que aún es útil para las personas con navegadores más antiguos, o en áreas más específicas, como editores de entrada de texto enriquecido que usan contentEditable . Dicho esto, como parte de nuestro trabajo de adjuntar eventos a las raíces, eliminamos mucha abstracción del sistema de eventos para que sea más fácil de entender y mejorar en el futuro. Como parte de React 17, estamos eliminando la "agrupación de eventos", que ha causado mucha confusión, y ya no estamos burbujeando el evento onScroll . Probablemente seguiremos deteniendo el burbujeo de eventos multimedia en React 18, acercando el comportamiento de React al del navegador. Guardamos algunos bytes con el nuevo sistema de eventos, pero fueron tomados por nuevas funciones en las que estamos trabajando, por lo que no conducirá a una disminución general del tamaño del paquete.

  • classNameclass (https://github.com/facebook/react/issues/4331, ver también https://github.com/facebook/react/issues/13525#issuecomment- 417818906 a continuación). Esto ha sido propuesto innumerables veces. Ya estamos permitiendo pasar class al nodo DOM en React 16. La confusión que esto crea no compensa las limitaciones de sintaxis contra las que intenta protegerse. No haríamos este cambio por sí solo, pero combinado con todo lo anterior tiene sentido. Tenga en cuenta que no podemos permitir ambos sin advertencias porque esto hace que sea muy difícil de manejar para un ecosistema de componentes. Cada componente necesitaría aprender a manejar ambos correctamente, y existe el riesgo de que entren en conflicto. Dado que muchos componentes procesan className (por ejemplo, al agregarlo), es demasiado propenso a errores.

Esta fue la parte más controvertida de la propuesta. Desde entonces, lanzamos Hooks, que fomentan la escritura de componentes de funciones. En componentes de función, generalmente sugerimos usar desestructuración para accesorios, pero no puede escribir { class, ... } porque sería un error de sintaxis. Entonces, en general, no está claro que esto sea lo suficientemente ergonómico como para seguir adelante. Creo que es plausible que revisemos esto en el futuro, o al menos hagamos que class no adviertan y dejen que la gente haga lo que quiera. Pero por ahora, dejaremos de lado esta idea.

Hola, es un gran artículo!
Solo quería saber si hay algún plan en proceso para reducir el tamaño de la producción de React-DOM. Para las aplicaciones móviles, sigue siendo una sobrecarga ya que el navegador analizará más de 100 KB de React-DOM JS y luego otros módulos. Luego, JS específico de la aplicación.
Para las páginas ricas en contenido, está provocando un mayor bloqueo y un mayor TTI.

¿Alguna idea de cuándo podremos ver tales cambios?

@morevolk-latei En sus mediciones, ¿cuánto tiempo se dedica a analizar 100 KB de ReactDOM?

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