React: [Umbrella] Liberando suspenso

Creado en 13 jul. 2018  ·  83Comentarios  ·  Fuente: facebook/react

Usemos este problema para rastrear las tareas restantes para lanzar Suspense a código abierto.

Versión inicial (MVP)

Centro

  • [x] API para leer el contexto desde cualquier función de la fase de procesamiento (@acdlite) [# 13139]
  • [x] Ocultar el contenido agotado en lugar de eliminarlo (@acdlite) [# 13120]
  • [] Inyección automática de proveedores de contexto por raíz de React (@acdlite) [# 13293]
  • [] Eliminar el prefijo unstable_ de AsyncMode (¿tal vez?)
  • [] Soporte para thenables síncronos y para promesas que se resuelven antes de que se complete la fase de renderizado.

    • [] Confirme que un thenable síncrono que arroja un error se maneja correctamente

  • [] Confirma que funciona con <div hidden> [# 13089]
  • [] ¿Por qué hacer clic en varios enlaces de detalles en el accesorio uno por uno eventualmente causa un gran marcador de posición incluso si espero cada uno de ellos por menos de la demora del marcador de posición antes de hacer clic en el siguiente ( ver tweet )?

Proveedor de caché simple

  • [] Invalidación de caché (@acdlite) [# 13337]
  • [] Suscripciones (@acdlite) [# 13337]
  • [] Decidir el nombre real

División de código

  • [x] Promesa de asistencia técnica como tipo de componente
  • [x] (tal vez) Código abierto lazyLoadComponent ?

Procesador de prueba

  • [] Finalice las API públicas por flushAll , yield , etc.

    • El plan tentativo es publicar comparadores personalizados para cada uno de los principales marcos de prueba, a la # 13236.

Docs

  • [ ] Entrada en el blog
  • [] React.Placeholder
  • [] proveedor-de-caché-simple
  • [] Biblioteca de división de código sin nombre

Seguimientos

Vencimiento suave (https://github.com/facebook/react/issues/14248)

  • [] Implementar una API para indicadores de carga in situ que no son ancestros
  • [] Asegúrate de que haya una forma de evitar que el indicador giratorio en línea parpadee si es lo suficientemente rápido

Procesador de servidor de transmisión

  • [] Implemente un renderizador de servidor de transmisión como el de la charla ZEIT de @acdlite
  • [] Hidratación parcial

Relacionado: Time Slicing Umbrella (https://github.com/facebook/react/issues/13306)

React Core Team Umbrella

Comentario más útil

@mschipperheyn

Este es un proyecto de varios años. La respuesta honesta es que generó mucho más trabajo del que pensamos cuando comenzamos hace dos años.

Pero la buena noticia es que debido a que ahora lo usamos mucho en producción, las piezas que faltan están claras y vemos el final del túnel. No es teórico: hay un conjunto finito de cosas que debemos terminar antes de poder decir cómodamente que está listo para una amplia adopción.

A continuación, se muestra un estado aproximado de diferentes flujos de trabajo en la actualidad:

  • <Suspense> API para dividir el código con lazy . ( enviado en React 16.6)

    • Como sabrá, ya puede usar este.

  • API de modo concurrente, por ejemplo, createRoot y useTransition . ( disponible en experimental )

    • Solución de compatibilidad para bibliotecas tipo Flux. ( en progreso @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • Cambiar el modelo de prioridades por uno más sensato. ( en progreso @acdlite , https://github.com/facebook/react/pull/18612)

    • Solo permita que finalice la última transición pendiente. ( en progreso @acdlite)

    • API fuera de pantalla (

    • Efectos de fuego al ocultar / mostrar contenido para Suspense

    • Efectos de fuego al ocultar / mostrar contenido para Fuera de pantalla

    • Muestre y oculte los niños del Portal cuando sea necesario

    • Alinear con el trabajo de estandarización en curso para la programación ( no iniciado )

    • Corregir errores importantes conocidos ( en progreso @gaearon y @acdlite)

    • Cambiar la semántica del evento. ( en progreso @sebmarkbage @trueadm)

    • Delegue a las raíces en lugar del documento para permitir una adopción más gradual ( en progreso , @trueadm)

    • Elimine los eventos discretos en la fase de captura.

    • Considere obtener la prioridad predeterminada de event para jugar mejor con el código imperativo.

    • Finalice otras semánticas y valores predeterminados de API. ( no iniciado )

    • Actualización de mecanografía y documentación.

  • Suspensión para la obtención de datos

    • El soporte de bajo nivel para señalar un componente no está listo para renderizarse (técnicamente también está disponible en React estable, pero esta API no se considera estable).

    • El renderizador del servidor elimina inmediatamente los fallbacks de Suspense ( disponible en versiones experimentales)

    • Una solución para casos de uso de GraphQL (Relay Hooks, enviado ).

    • Una solución para casos de uso que no son de GraphQL ( en progreso @sebmarkbage en colaboración con Next.js).

    • Un paquete de integración para dependencias basadas en datos. ( en curso )

    • Finalizar la API de bloques, incluido el contexto.

    • Una solución de almacenamiento en caché genérica. ( no iniciado )

    • Algún tipo de integración de enrutador.

Casi se siente como "Está en producción en Facebook, así que hemos terminado".

Puedo ver cómo podría verse de esta manera, aunque tbh esta lectura es un poco desmoralizante. :-) Hemos estado trabajando sin parar en esto durante todos los últimos meses, y muchos de los aspectos técnicos están terminados o cerca de terminarse. La mayoría de las obras restantes se dividen en dos categorías:

  • Arreglando los defectos que descubrimos en los diseños iniciales antes de cementarlos en una versión estable. Si tuviéramos que publicar lo que tenemos ahora, tendríamos que seguir adelante con cambios importantes en unos pocos meses. Eso solo sería confuso.

  • Compatibilidad del ecosistema y buenos valores predeterminados. No ayuda si lanzamos algo que nadie puede usar hoy porque no funciona con sus bibliotecas o enfoques existentes. Entonces, la mayor parte del trabajo (por ejemplo, compatibilidad con bibliotecas tipo Flux a través de useMutableSource , elegir una mejor semántica de eventos, enviar una estrategia de almacenamiento en caché recomendada) consiste en garantizar que realmente pueda usar lo que publicamos. Esta es una cola larga.

En términos de "puedes usar hoy" ... Técnicamente, puedes usar todo esto hoy. Hacemos. Específicamente, usamos Relay Hooks y Concurrent Mode. Todavía tenemos importantes cambios planificados y problemas conocidos, por lo que el estado actual no cumple con el estándar en el que lo consideraríamos listo para una amplia adopción. Por supuesto, si no le importa que los errores o las API cambien justo en sus manos, puede usar las versiones @experimental como lo hacemos nosotros.

Yo no diría que Facebook está en una posición especial aquí en términos de que "terminamos". Muy por el contrario, no hemos terminado - pero internamente, estamos dispuestos a tolerar la pérdida de clientes y la acumulación en la parte superior de un tren en movimiento, porque eso es lo que sabemos lo que estamos construyendo es sólido. Sin esta intensa comida para perros, las fallas que descubrimos en seis meses tomarían varios años para descubrirlas y rediseñarlas.

En resumen: hay más trabajo por hacer.

Todos 83 comentarios

Exponer unstable_AsyncMode (¿tal vez?)

¿No está esto ya expuesto ?

Quise decir eliminar el unstable_

Espero el código abierto de la biblioteca de división de código sin nombre 💯

¿Qué significa [Umbrella]? 🤔☂️

Esto significa que es una característica que afecta a varios proyectos / paquetes / herramientas.

@ghoullier Ya veo, ¡muchas gracias!

Hola @acdlite , solo una pregunta sobre cómo prepararse mejor para esto. No pidiendo / esperando ningún tipo de línea de tiempo, pero preguntándose:

¿Actualmente espera que estas características se incluyan en React 16 y sean fáciles de adoptar de forma incremental, como la nueva API de contexto que llegó con 16.3?

¿O estás pensando que será algo que empujará a React a v17 y requerirá más trabajo para adoptarlo?

Preguntando porque estoy trabajando en una hoja de ruta que se cruza significativamente con casi todo lo que está en su lista y estoy tratando de encontrar la mejor manera de lidiar con eso.

¿También tiene algún consejo sobre cómo prepararse mejor (en términos de código escrito hoy, que quiere ser compatible en el futuro con estas mejoras de React) - polyfills / técnicas / etc?

(disculpas si estas preguntas se responden en otro lugar y las he perdido)

Añadiendo otra pregunta a las preguntas de @JedWatson :

  • Tampoco necesitamos / esperamos obtener una línea de tiempo para una versión estable, pero ¿sería posible / útil obtener una nueva versión preliminar? (AFAIK, la versión más reciente es 16.4.0-alpha.0911da3 de febrero).

¡Gracias! ❤️

En mi opinión, proporcionarán una publicación de blog como antes antes de que se aterrice.

Y creo que no necesita prepararse demasiado porque no hay un cambio importante (tiene muchas características que tal vez parezcan diferentes / entren en conflicto con las prácticas actuales, como redux fetch con suspenso, pero habrá una codificación o encapsulación fácil para hacer esto, ya sabes, fb tiene componentes de 3W +). Y si ve la charla de @acdlite (sobre el suspenso @gaearon (sobre el suspenso del cliente en islandia), sabrá que no tiene que preocuparse demasiado y que no es invasivo.

Por cierto, puede buscar la clave 'Umbrella' en el repositorio y encontrará más información como # 8830 y # 12152

AFAIK, la versión más reciente es 16.4.0-alpha.0911da3 de febrero.

IIRC, ¿esto es un mal funcionamiento?

Estoy trabajando en la implementación del módulo de suspenso y las nuevas API en Facebook. En caso de que @acdlite esté ocupado con otra cosa, me gustaría compartir algunos de mis pensamientos sobre nuestra experiencia en Facebook y responder algunas preguntas de @JedWatson.

¿Actualmente espera que estas características se incluyan en React 16 y sean fáciles de adoptar de forma incremental, como la nueva API de contexto que llegó con 16.3?

No estoy seguro si vendrá con React 16 o 17. Según el equipo de React, es probable que se lance antes de finales de este año, lo que depende de qué tan bien se ejecute en Facebook y cómo esté lista la API relacionada o no. Pero en cuanto al código, me complace decir que sería fácil de adoptar, porque hemos estado experimentando durante bastante tiempo en Facebook. La función de suspenso seguirá funcionando para el código base existente. Pero con cambios adicionales (como la representación asíncrona), tendrá más ventajas que las que le brindará la nueva función.

¿Tiene algún consejo sobre cómo prepararse mejor (en términos de código escrito hoy, que quiere ser compatible en el futuro con estas mejoras de React) - polyfills / técnicas / etc?

Yo diría que la migración es bastante incremental y progresiva. Como dijo @ NE-SmallTown, no queremos introducir cambios importantes. También sería doloroso implementarlo en Facebook porque tenemos una base de código muy grande. Pero hasta ahora, la implementación ha sido fluida y no requiere que hagas cambios adicionales.

@JedWatson

¿Actualmente espera que estas características se incluyan en React 16 y sean fáciles de adoptar de forma incremental, como la nueva API de contexto que llegó con 16.3?

Incrementalmente. Siempre de forma incremental :) De lo contrario, no podríamos enviar esto a Facebook.

Esto es lo que espero:

| | Cliente | Representación del lado del servidor |
| ----------------- | ---------------------------- | - -------------------------------------------- |
| Suspense | Funciona en todas partes * | Las mismas restricciones que el renderizador de servidor existente |
| Representación asincrónica | Inscríbase usando <AsyncMode> | Las mismas restricciones que el renderizador de servidor existente |

* En el modo de sincronización, delayMs siempre es 0 . Los marcadores de posición aparecen de inmediato.

Suspense funcionará sin cambios en sus componentes existentes. En un momento pensamos que podríamos requerir compatibilidad con <StrictMode> , pero durante nuestras pruebas internas descubrimos que una de las mejores formas de actualizar al modo estricto era usar Suspense. El dilema del huevo y la gallina. Así que encontramos una manera de hacerlo funcionar incluso fuera del modo estricto.

Entonces, la idea es que los usuarios comiencen a migrar a Suspense incluso antes de que estén listos para migrar a la representación asincrónica. Luego, una vez que un subárbol está listo, pueden optar por incluir <AsyncMode> .

Sin embargo, para las nuevas aplicaciones, la historia es diferente: vaya asincrónico de forma predeterminada. Presentaremos una nueva API raíz (un reemplazo de ReactDOM.render ) que es solo asincrónica.

Habrá un período incómodo después del lanzamiento inicial en el que muchos marcos de terceros (Redux, Apollo, React Router ...) pueden no funcionar correctamente en modo asíncrono. Eso podría dañar la adopción por un tiempo. Pero la idea es que las nuevas funciones serán tan atractivas que las bibliotecas no tardarán en adaptarse o ser reemplazadas por una alternativa compatible con asincrónica.

¿También tiene algún consejo sobre cómo prepararse mejor (en términos de código escrito hoy, que quiere ser compatible en el futuro con estas mejoras de React) - polyfills / técnicas / etc?

Envuelva todo en <StrictMode> y asegúrese de que no haya advertencias. Tendremos guías de migración más detalladas a medida que nos acerquemos al lanzamiento.

Habrá un período incómodo después del lanzamiento inicial en el que muchos marcos de terceros (Redux, Apollo, React Router ...) pueden no funcionar correctamente en modo asíncrono.

Apollo no lo hace incómodo, ¡estaremos listos! 🕺😳

Sin embargo, en serio, nosotros: corazón: todas las cosas de React, por lo que asegurarnos de que estamos en línea con estos cambios para el lanzamiento inicial no solo es una alta prioridad, ¡sino que también es algo que nos entusiasma mucho! ¡Gracias por todo su increíble trabajo en este @acdlite!

Voy a intervenir y decir que el equipo de Redux está trabajando en compatibilidad asíncrona para React-Redux.

Presenté una hoja de ruta potencial en https://github.com/reduxjs/react-redux/issues/950 . TL; DR:

  • Es de esperar que React-Redux 5.1 funcione con <StrictMode> sin advertencias (PR actual: https://github.com/reduxjs/react-redux/pull/980)
  • 6.0 será una reescritura interna para usar la nueva API de contexto, agregar reenvío de referencias y posiblemente otros cambios, pero intente mantener la mayor cantidad posible de la API pública actual (es decir, <Provider> y connect() ). Veremos qué tan bien funciona con la representación asíncrona y descubriremos el mejor camino a seguir. (Mi PR de prueba de concepto anterior está en https://github.com/reactjs/react-redux/pull/898, pero probablemente lo rehagaremos basándonos en otras lecciones aprendidas del trabajo 5.1). esta versión requeriría React 16.5 como mínimo, debido a la necesidad de un nuevo contexto y probablemente también al PR "contexto de lectura de métodos de ciclo de vida" aún no publicado que acaba de fusionarse.
  • Después de eso, estamos abiertos a ideas para una API React-Redux diferente (sí, sí, eso posiblemente incluye accesorios de renderizado, personas).

Agradeceríamos más ojos en nuestro WIP y, con suerte, la gente nos puede dar más comentarios y discusiones sobre cómo están viendo el uso de Redux con React Suspense y la representación asíncrona para que podamos asegurarnos de que los casos de uso se cubran adecuadamente. También esperamos tener más discusiones con el equipo de React sobre exactamente con qué restricciones necesitamos trabajar, y sería útil si pudiéramos obtener algunas aplicaciones de muestra que nos permitan ver qué problemas debemos resolver para todos. esto para que funcione correctamente.

esperando el lanzamiento de Async rendering y Suspense

@acdlite También pregunta sobre suspenso y renderizado asíncrono.
Mi pregunta es una vez que se introducen y uno comienza a escribir aplicaciones con esa nueva versión de react: ¿significa que la API de react y la forma en que las personas codifican también cambiarán? (¿incluso si no planean usar funciones de suspenso y renderizado asíncrono?)

Supongo que puede ser más complicado escribir código de reacción con suspenso y renderizado asíncrono (tal vez debido a una nueva API u otras restricciones), y para aquellos que no lo necesitan, ¿por qué obligarlos a usar react de una nueva manera? ¿Y no permitirles reaccionar de la forma en que lo hacen ahora?

Supongo que puede ser más complicado escribir un código de reacción con suspenso

¿Ha tenido la oportunidad de ver la segunda mitad de mi charla? Yo diría todo lo contrario: es mucho menos complicado usar el suspenso para la obtención de datos que cualquier otra cosa (incluido Redux, el estado local o alguna otra biblioteca).

@gaearon no lo he hecho. Hablaba más en teoría. Imagina que ya hay un conjunto de personas que saben reaccionar. Si las personas no necesitan la función de renderizado asíncrono y suspenso, ¿por qué obligarlas a aprender a reaccionar "nuevas"? ¿Especialmente si el "nuevo" react es más complicado de usar? Pero: no estoy bien informado, por lo que podría estar equivocado, digamos sobre la parte "más complicada": solo estoy compartiendo algunos de mis pensamientos :).

En cierto modo, estoy diciendo que si el 10% de las aplicaciones necesitan la función de suspensión y renderizado asíncrono, ¿por qué en esos otros casos del 90% obligar a las personas a aprender a reaccionar "nuevas"? Pero, de nuevo, podría estar equivocado, ya que todavía no reuní mucha información sobre la suspensión y la representación asíncrona.

Creo que es difícil tener una conversación si aún no has mirado mis demos .

Para ser claros: no hay un "nuevo React", estas características no rompen ningún patrón existente 🙂. Son aditivos. Tampoco necesita escribir código de una manera completamente diferente para usar esas funciones, aunque algunas de ellas solo funcionan si usa métodos modernos de ciclo de vida .

Si bien esto no está directamente relacionado con su preocupación, no estoy de acuerdo con que sean "más difíciles de usar". Creo que el suspenso es mucho más sencillo de usar que cualquier otro mecanismo de carga que existe actualmente. Esa es la razón por la que estoy tan emocionado. Pero nuevamente, no tiene que usar ninguna de las nuevas funciones si no lo desea. Los viejos patrones seguirán funcionando.

Realmente recomiendo ver mi charla . Estoy seguro de que esto tendrá mucho más sentido una vez que vea estas funciones en acción.

@gaearon

Todos los viejos patrones siguen funcionando.

Gracias por tus comentarios, Dan. Sí, así es como pensé, supongo que si las personas no necesitan esas funciones, deberían poder escribir como solían hacerlo antes de que se añadieran esas funciones.

buena suerte.

Hola Dan (@gaearon), no soy quisquilloso, pero quiero averiguarlo. Arriba dijiste:

Pero nuevamente, no tiene que usar ninguna de las nuevas funciones si no lo desea. Los viejos patrones seguirán funcionando.

Lo que sugeriría que puedo codificar en el nuevo React de la misma manera que lo hice en el "antiguo" React, por ejemplo, podría usar los métodos del ciclo de vida de la misma manera, etc., ¿verdad?

Sin embargo, aquí , bvaughn dice que getDerivedStateFromProps (o componentWillReceiveProps) podría ser llamado muchas veces para una actualización, de ahí su solución para no buscar datos dentro de él.

Entonces, mi pregunta es, después de todo, parece que no podemos usar el nuevo React exactamente de la misma manera que antes, ¿verdad? Debido a que AFAIK en el componente de reacción actual WillReceiveProps no se llama muchas veces para una actualización, ¿no es así?

@ giorgi-m: sí, los métodos del ciclo de vida están cambiando, pero el punto es que Suspense en sí es una función opcional. Todos sus métodos de renderizado de React existentes y el comportamiento de renderizado de React funcionarán como están. Sin embargo, _si_ opta por agregar una etiqueta <AsyncMode> a una parte de su aplicación, _y_ comienza a utilizar el enfoque de Suspense para indicar las necesidades de datos asíncronos, _entonces_ puede aprovecharlo. Nada de eso sucede si no agrega eso a su código base.

@ giorgi-m componentDidUpdate debe usarse en lugar de componentWillReceiveProps o getDerivedStateFromProps .

@markerikson ¿Entonces dices que lo que dijo bvaughn aquí , que _getDerivedStateFromProps_ puede ser llamado muchas veces para una actualización, no es necesariamente el caso, si no he habilitado el <AsyncMode/> ?
(lo siento por hacer preguntas como estas, solo me aparecen de vez en cuando y no encontré recursos que las cubrieran todas).

PD. bvaughn tampoco mencionó la opcionalidad de eso en el hilo vinculado, por lo que levantó mis sospechas.

¿Debería agregarse un método para poner en cola actualizaciones asincrónicas (por ejemplo, deferSetState() para componentes de clase en lugar de unstable_deferredUpdates() específicos del renderizador) a la lista de verificación principal?

Según tengo entendido, cualquier actualización de fibras en asíncrono mode será asincrónica, lo que en teoría significa que deferSetState() sería innecesario. Sin embargo, la demostración unstable-async/suspense mezcla una actualización sincrónica y una actualización asincrónica y no estoy seguro de cómo se puede lograr en el modo async (para componentes "universales").

Está en la lista de verificación del paraguas de corte de tiempo.

Promesa de soporte como tipo de componente

Relacionado con esto, cuando tenga:

const PromiseType = new Promise(() => {})
class A extends Component {
    componentDidMount() {}
    componentDidUpdate() {}
    render() {
        return <div><PromiseType></PromiseType></div>
    }
}

¿Hay alguna heurística sobre cuándo se llamarían los ciclos componentDidUpdate vida componentDidMount y componentDidUpdate ?

  1. Cuando todos los niños se hayan resuelto (incluida la promesa), lo que en este caso significa que no los llamarán dado que la promesa nunca se resuelve.
  2. ¿Cuando todos los niños anfitriones inmediatos hayan sido entregados?

@thysultan : componentDidMount y componentDidUpdate se llaman en la fase de confirmación, cuando un árbol de IU se ha renderizado y aplicado por completo al DOM.

Entonces, según mi comprensión de Suspense, creo que la respuesta es que la instancia A nunca se montaría realmente. Si PromiseType _did_ se resolvió, pero uno de sus descendientes adicionales también intentó esperar una promesa que nunca se resuelve, nunca volvería a montarse. Por lo tanto, cDM y cDU nunca se ejecutarían en esos ejemplos.

(Alguien no dude en corregirme si mis suposiciones son incorrectas aquí :))

Sí, componentDidMount o componentDidUpdate solo se ejecutan en la fase de confirmación, que solo se ejecuta después de que se haya resuelto todo el árbol . Este árbol puede incluir algunos marcadores de posición que ha puesto explícitamente allí (dependiendo de si algo dentro de ellos todavía se suspende después de que hayamos esperado lo suficiente), pero si representa explícitamente un niño sin un marcador de posición a su alrededor, nunca podrá terminar en una situación en la que "no está listo".

Tengo muchas ganas de poder jugar con esto (incluso navegué a través de una gran cantidad de código fuente solo para descubrir que aún no había puesto una versión funcional de esto en la red mundial).

¿Hay algo que podamos hacer para ayudar a que esto se publique? :D

Puedes compilar desde master si quieres jugar. Vea las instrucciones en fixtures/unstable-async/suspense

@gaearon ¿Tengo razón en que esto está en su estado actual solo en el lado del cliente (por lo que se debe hacer más para admitir la representación del lado del servidor)?

EDITAR, encontró la respuesta: para cualquier otra persona que busque ansiosamente el uso de Suspense en SSR para aplicaciones universales. Encontré este comentario de Dan que nos permite saber que esto es del lado del cliente solo por ahora. Sin embargo, ese comentario también apunta a https://www.youtube.com/watch?v=z-6JC0_cOns que habla sobre las posibles implicaciones para SSR.

De hecho, pronto comenzaremos a trabajar en relación con el caso de SSR.

Imagine este escenario en una aplicación React asíncrona que se ejecuta en un dispositivo móvil de gama baja:

  1. Hay una carga de anuncios externos, usando toda la CPU (😓)
  2. El usuario hace clic en un enlace y el enrutador activa un nuevo renderizado
  3. React está en modo asíncrono, por lo que espera hasta que Chrome / Safari le dé permiso para usar la CPU, pero el anuncio sigue cargándose durante 3 segundos más.
  4. El usuario cree que la aplicación no funciona.

Este problema podría evitarse usando la misma técnica <Placeholder> discutida para Suspense, mostrando una ruleta después de 1 segundo, por ejemplo.

¿Se ha considerado este escenario? ¿Funcionará <Placeholder> para representaciones asíncronas lentas?

@luisherranz Hay dos mecanismos para evitar esto:

  1. React tiene una fecha límite asociada con cada actualización. Las actualizaciones de clics y otras interacciones como esta deberían descargarse en ~ 150ms, a menos que opte explícitamente por una fecha límite más larga (por ejemplo, para actualizaciones no esenciales). Entonces, React forzará sincrónicamente la descarga si algo está acaparando el hilo.

  2. React ya no usa requestIdleCallback porque, de hecho, los navegadores no son lo suficientemente agresivos para programarlo. El enfoque de programación exacto también puede cambiar con el tiempo, pero esto definitivamente es algo que nos importa.

Muchas gracias por la rápida respuesta Dan.

  1. React tiene una fecha límite asociada con cada actualización

Impresionante. ¿Existe ya una API que podamos probar?

  1. React ya no usa requestIdleCallback porque, de hecho, los navegadores no son lo suficientemente agresivos para programarlo.

Eso es lo que también hemos experimentado. A veces, en una aplicación abarrotada con anuncios externos e incrustaciones de twitter o youtube, pueden pasar varios segundos hasta que se llame al requestIdleCallback y finalice el procesamiento. Entonces 👍 a eso.

Por cierto, para nosotros hay otro caso de uso relacionado con su primera respuesta: estamos tratando de usar cargas diferidas con dos compensaciones. El primero desencadena un renderizado asincrónico, el segundo desencadena un renderizado sincronizado si el async no ha terminado. Algo como esto:

  1. El usuario se desplaza hacia abajo y está a 1200px de un elemento pesado: por ejemplo, la próxima publicación de un blog.
  2. La primera ofensa desencadena un renderizado asíncrono de la siguiente publicación.
  3. El usuario sigue desplazándose hacia abajo y está a 600 px de la siguiente publicación.
  4. El segundo desplazamiento desencadena: si la publicación asíncrona ha finalizado (se ha llamado a componentDidMount) no sucede nada, pero si no, desencadena un renderizado sincronizado de toda la publicación.

Entonces, en lugar de tiempo, nos gustaría controlar la descarga con un segundo disparador. ¿Tiene sentido? ¿Podria ser posible?

¿Existe ya una API que podamos probar?

No estoy seguro de si te refieres a maestro o no (el modo asíncrono no está oficialmente disponible en las versiones de npm), pero el tiempo de vencimiento se asigna automáticamente a cada actualización. Para eventos como clics, es ~ 150ms en modo prod. No puede configurarlo, aunque puede optar por una actualización diferida (más larga) si lo desea con una API inestable especial.

Entonces, en lugar de tiempo, nos gustaría controlar la descarga con un segundo disparador. ¿Tiene sentido? ¿Podria ser posible?

Sí, es posible. Describí un mecanismo como este aquí: https://github.com/oliviertassinari/react-swipeable-views/issues/453#issuecomment -417939459.

No estoy seguro de si te refieres a maestro o no (el modo asíncrono no está oficialmente disponible en las versiones de npm)

Sí, estamos usando el paquete npm con <unstable_AsyncMode> , flushSync y unstable_deferredUpdates .

¡Por favor, comience a lanzar versiones alfa / beta con estos cambios en npm! 🙏

Sí, es posible. Describí un mecanismo como este aquí: oliviertassinari / react-swipeable-views # 453 (comentario).

Brillante. Mucho mejor que nuestra implementación actual usando unstable_deferredUpdates :)

No puedo esperar para comenzar a usar <div hidden> . Están haciendo un trabajo increíble.

@luisherranz Cuidado, esas cosas _son_ inestables. Puede tener errores o ser bastante ineficaz (por ejemplo, una optimización crucial - "reanudar" - aún no está implementada). También eliminaremos unstable_deferredUpdates a favor del nuevo módulo schedule ( schedule.unstable_scheduleWork ).

Sí, lo estamos usando solo para una pequeña parte de la aplicación y probando intensamente, pero hasta ahora todo va bien :)

PUEDE SER OFFTOPIC:
requestIdleCallback se llama solo 20 veces por segundo: Chrome en mi máquina Linux con núcleo 6x2, no es realmente útil para el trabajo de la interfaz de usuario.
requestAnimationFrame se llama con más frecuencia, pero es específico para la tarea que sugiere el nombre.

Hemos dejado de usar requestIdleCallback por este motivo.

¿Qué están usando todos ustedes en lugar de requestIdleCallback ?

Ah, por supuesto. Tonto de mí. Me preguntaba qué API del navegador usa el módulo del programador debajo del capó en lugar de requestIdleCallback . Debería haber presentado la pregunta con más claridad. 😅

Hola,

mientras trataba de entender Suspense, reconocí que no tengo idea de qué parte de una aplicación está realmente "suspendida" al usar el componente Suspend 😳😱.

En el siguiente ejemplo, esperaría que Title sea ​​visible inmediatamente, Spinner después de 1000ms y UserData después de ~ 2000ms (ya que "cargar" los datos de ese componente tarda 2000ms).
Pero lo que veo es que Title aparece primero junto con Spinner después de 1000ms.

// longRunningOperation returns a promise that resolves after 2000ms
const UserResource = createResource(longRunningOperation);

function UserData() {
  const userData = UserResource.read(cache, "Lorem Ipsum");
  return <p>User Data: {userData}</p>;
}

function Spinner() {
  return <h1>Fallback Loading Spinner</h1>;
}

function Title() {
  return <h1>Hello World</h1>;
}

function App() {
  return (
    <React.Fragment>
      <Title />
      <Suspense maxDuration={1000} fallback={<Spinner />}>
        <UserData />
      </Suspense>
    </React.Fragment>
  );
}

unstable_createRoot(document.getElementById("mount")).render(<App />);

(Puede encontrar el ejemplo completo que usa React 16.6.0-alpha.8af6728 aquí en codesandbox )

¿Hay alguna manera de hacer que Title inmediatamente visible y "suspender" solo la otra parte de la aplicación? ¿O entendí mal el suspenso por completo? (Si hay una mejor manera de hacer este tipo de preguntas, hágamelo saber)

¡Gracias!

¡Hola @nilshartmann! ¡Gran pregunta!

¿Hay alguna manera de hacer que el título sea visible de inmediato y "suspender" solo la otra parte de la aplicación?

Si lo entiendo correctamente, tendrá que decirle explícitamente a React que _no esperar_ antes de descargar Title al DOM como en este ejemplo para hacer Title inmediatamente visible y "suspender" solo el otro parte de la aplicación envolviendo las partes que esperaría que se renderizaran inmediatamente en un <Suspense maxDuration={0}> .

Me imagino que este es el caso debido a algunas mecánicas subyacentes del programador de nivel inferior. También me encantaría entender esto mejor, pero eso debería resolver tu problema por ahora.

Estoy emocionado de escuchar lo que realmente está sucediendo allí.

(Si hay una mejor manera de hacer este tipo de preguntas, hágamelo saber)

No estoy seguro de que lo haya. 😄 Me parece bastante claro. ¡Gracias por preguntar!

@TejasQ En mi navegador, cargar su ejemplo muestra la ruleta alternativa de inmediato. ¿No debería cargarse después de 1000 ms?

@TejasQ gracias por tu respuesta, pero @karlhorky tiene razón: ahora la ruleta aparece de inmediato.

¡Ay! Me lo perdí. Lo intenté. 😅Déjame echarle otro vistazo y volver contigo. Debo haber olvidado algo. 🤷‍♂️

~ Actualización: estoy tratando de resolverlo aquí y podemos colaborar si alguien está interesado en hacerlo juntos en tiempo real. ~

Segunda actualización: @ philipp-spiess y yo lo he mirado y estoy realmente perplejo. Todavía no lo entiendo. En este punto, no estoy seguro de si se trata de un error, ya que esto es, de hecho, una función unstable_ y alpha, o si es algo que simplemente no veo.

En cualquier caso, creo que el equipo central tendrá respuestas útiles o podrá usar su pregunta para hacer que React sea aún mejor / más accesible.

Veamos qué tienen que decir. 😄 ¡Gracias por señalar esto, @nilshartmann!

¿Fue lanzado como parte de React v16.6? La publicación del blog muestra un código de ejemplo usando Suspense:

import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() (
  <Suspense fallback={<div>Loading...</div>}>
    <OtherComponent />
  </Suspense>
);

¿Fue lanzado como parte de React v16.6?

Solo el caso de uso de carga diferida, y solo en modo de sincronización. El modo concurrente sigue siendo WIP.

@nilshartmann

En el siguiente ejemplo, esperaría que Title sea visible inmediatamente, Spinner después de 1000ms y UserData después de ~ 2000ms (ya que "cargar" los datos para ese componente toma 2000ms).

Creo que estás un poco confundido acerca de lo que hace maxDuration . Es un nuevo modelo mental, pero aún no hemos tenido tiempo de documentarlo. Así que seguirá siendo confuso durante un tiempo hasta que el modo concurrente esté en una versión estable.

Felicitaciones por anunciar la propuesta de Hooks. Me gustaría compartir algo con el equipo. Hace un tiempo lancé un componente llamado React Async , que tiene características similares a Suspense. Esencialmente, maneja la resolución de Promise y proporciona metadatos como isLoading, startedAt y métodos como reload y cancel, todo con una API declarativa (y un gancho useAsync está en camino).

Ahora mi principal preocupación es cómo se integrará esto con Suspense. En su mayor parte, probablemente pueda usar las API de Suspense de React Async y proporcionar a los usuarios la API React Async familiar y simple, al tiempo que ofrezco las funciones de programación de Suspense de forma gratuita. Por lo que he visto, realmente creo que la API React Async es más sensible y accesible en comparación con las API de Suspense más abstractas. Básicamente, React Async intenta ofrecer una API más concreta que funcione para un subconjunto de casos de uso un poco más pequeño.

Me sorprendió conocer la biblioteca React Cache. Para React Async, deliberadamente no incluí un mecanismo de caché, pero elegí lidiar con las promesas de vainilla. Agregar almacenamiento en caché además de eso es bastante fácil.

Finalmente, me preocupa acceder a las funciones de Suspense desde ganchos personalizados. El suspenso parece depender en gran medida de varios componentes incorporados, lo que hace que sea imposible (¿creo?) Usarlos desde un gancho. ¿Habrá ganchos de suspenso? ¿O hay alguna otra forma de integrar los dos?

Hola. ¿Cómo puedo probar el código con Suspense / Lazy?
ahora renderer.create (...) toTree () lanza
"toTree () aún no sabe cómo manejar los nodos con etiqueta = 13"

Por qué los accesorios maxDuration en Suspense solo se usan en Concurrent Mode lugar de en modo sincronizado y concurrente. ¿Alguien puede ayudar a explicar?

(En este momento) significa cuánto tiempo se permite que Concurrent Mode deje este árbol pendiente antes de obligarlo a comprometerse; controla efectivamente la fecha límite de división de tiempo y la división de tiempo no existe en el modo Sync. Esperar antes de confirmar el árbol necesariamente haría que la confirmación ... no la sincronización.

He estado usando Suspense en una aplicación interna para la obtención de datos y rápidamente descubrí la razón por la que todavía no está destinado a ser utilizado para la obtención de datos.

Sin embargo, eventualmente, está destinado a ser utilizado para obtener datos. Dado que parece poco probable que la API cambie significativamente, excepto quizás por el proveedor de caché, ¿cómo se supone que funcione Suspense si necesita modificar los datos después de haberlos obtenido?

Como ejemplo, aquí hay un gancho realmente horrible de mi aplicación.

function useComponentList(id) {
  const incomingComponents = useSuspenseFetch(
    React.useCallback(() => getComponentAPI().listComponents(id), [id])
  )

  const map = React.useMemo(
    () =>
      Map(
        (incomingComponents || []).map(component => [component.id, component])
      ),
    [incomingComponents]
  )

  return useCacheValue(map)
}

Este gancho:

  1. Obtiene datos usando la devolución de llamada dada desde el punto final dado
  2. Transforma esos datos en un mapa ImmutableJS: dado que esto es potencialmente costoso, memorizo ​​la operación.
  3. Devuelve el mapa envuelto en useCacheValue , que es el bit particularmente incómodo.

useCacheValue ve así:

export default function useCacheValue(value) {
  const [state, setState] = React.useState(value)
  React.useEffect(() => {
    setState(value)
  }, [value])

  return [state, setState]
}

con la idea de que es un gancho que responderá al cambio de value (lo que indica que los datos se recuperaron) pero permite al usuario modificar la representación de las aplicaciones de reacción de ese estado. En cierto modo, actúa como un caché muy malo (de ahí el nombre).

Estoy luchando por ver cómo funciona bien este patrón con Redux en su estado actual. ¿Ha habido algún descubrimiento sobre cómo podría verse esto cuando lo escribe un programador que no soy yo y cuando el suspenso está "listo" para la búsqueda de datos? Tal como está, esto es mucho más laborioso que usar Redux solo con banderas de búsqueda imperativas.

Esto probablemente se vuelva mucho más simple una vez que Redux tenga sus propios ganchos, ya que la principal dificultad para hacer que los dos jueguen juntos es que Redux usa un HOC con un contexto que no está destinado a ser expuesto, pero aún me gustaría ver lo que el oficial la respuesta es :)

Suspense está destinado a funcionar con un caché externo ( no un Hook controlado por estado). Proporcionaremos una implementación de referencia de dicho caché que funciona para casos de uso simples. Relay implementará su propio mecanismo de almacenamiento en caché. Cualquier otra herramienta (como Apollo) también podrá implementar su propia caché que sea compatible, posiblemente inspirándose en estas dos implementaciones.

La mutación / invalidación no es la única pregunta que necesita respuesta. También debemos pensar en: cuándo mostrar los hiladores, patrones comunes como "indicador en línea" que puede estar fuera del árbol suspendido, coordinando los estados de carga (para cosas que deben desbloquearse en un orden de arriba hacia abajo o entrar como están ready), reproducción en streaming de listas, cómo afecta esto a la hidratación parcial, etc. Estamos trabajando en estas cosas, pero todavía no hay una "recomendación oficial" sobre ninguna de ellas. Cuando lo haya, lo sabrá por el blog donde anunciamos actualizaciones.

Como nota al margen, Suspense para la búsqueda de datos es un modelo mental suficientemente diferente al que la gente podría estar acostumbrada. No creo que sea justo esperar que sea necesariamente tan poderoso cuando se integra con mecanismos muy libres como Redux. Pero ya veremos. Es difícil decir algo ahora mismo.

@gaearon Cuando dices "estamos trabajando en estas cosas", ¿hay

Gracias, @gaearon :)

@ntucker Como siempre, puede ver la actividad en curso como RP. Por ejemplo: https://github.com/facebook/react/pull/14717 , https://github.com/facebook/react/pull/14884 , https://github.com/facebook/react/pull/15061 , https://github.com/facebook/react/pull/15151 , https://github.com/facebook/react/pull/15272 , https://github.com/facebook/react/pull/15358 , https : //github.com/facebook/react/pull/15367 , y así sucesivamente. Intentamos poner algo de información descriptiva en cada RP, y puedes ver los cambios de comportamiento de las pruebas. La barra de documentación para experimentos es baja por varias razones.

Publicaremos explicaciones más completas sobre el modelo elegido cuando estemos más seguros de que realmente funciona. No creo que sea productivo ni para nosotros ni para la comunidad si describimos minuciosamente cada experimento en detalle a medida que ocurre. La mayoría de nuestros primeros experimentos fallan, y documentar y explicar todos y cada uno de ellos ralentizaría nuestro trabajo.

Es incluso peor que esto a menudo da como resultado que las personas construyan un modelo mental en torno a algo que luego nos damos cuenta de que no funciona de la manera originalmente diseñada. (Como está sucediendo con maxDuration que acabamos de eliminar). Por lo tanto, preferiríamos no compartir ideas a medias hasta que sea un buen uso tanto de su tiempo como de nuestro tiempo. Esto también es consistente con cómo desarrollamos React en el pasado. Cuando algo esté realmente listo (incluso para una redacción teórica del modelo mental), centraremos toda nuestra atención en documentarlo y explicarlo.

Como nota al margen, Suspense para la búsqueda de datos es un modelo mental suficientemente diferente al que la gente podría estar acostumbrada. No creo que sea justo esperar que sea necesariamente tan poderoso cuando se integra con mecanismos muy libres como Redux. Pero ya veremos. Es difícil decir algo ahora mismo.

@gaearon , afortunadamente, el modelo mental de Suspense

La hoja de ruta anunciada en noviembre pasado (https://reactjs.org/blog/2018/11/27/react-16-roadmap.html) indicó que la versión "concurrente" de Suspense estaba programada para el segundo trimestre de 2019. Ahora estamos bien en Q3 2019. ¿Hay alguna actualización que podamos obtener en términos de definitivamente no Q3, o quizás Q3, etc.?

Esta fue la última actualización de la hoja de ruta que pude encontrar: https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#an -update-to-the-roadmap

Proporcionamos una versión experimental en octubre: https://reactjs.org/docs/concurrent-mode-intro.html. Esta es la misma compilación que estamos ejecutando en producción. Todavía hay más trabajo por hacer (tanto en términos de ajustar la API como de crear API de nivel superior), pero puede comenzar a jugar con él si lo desea.

El suspenso me esta matando

@gaearon Entiendo que lo usas en producción. Pero soy muy reacio a utilizar código "experimental" en producción. Ustedes no están siendo claros sobre la hoja de ruta, el estado, el progreso, los tiempos, etc. ¿Es esto alfa, beta, calidad RC? Este término "experimental" me dice "no me toques esto".

Todos estamos depositando nuestros negocios en este código y estoy seguro de que todos estamos tan abrumados como ustedes. Un poco de claridad, un blog, ALGO realmente ayudaría. Casi se siente como "Está en producción en Facebook, así que hemos terminado".

@mschipperheyn

Este es un proyecto de varios años. La respuesta honesta es que generó mucho más trabajo del que pensamos cuando comenzamos hace dos años.

Pero la buena noticia es que debido a que ahora lo usamos mucho en producción, las piezas que faltan están claras y vemos el final del túnel. No es teórico: hay un conjunto finito de cosas que debemos terminar antes de poder decir cómodamente que está listo para una amplia adopción.

A continuación, se muestra un estado aproximado de diferentes flujos de trabajo en la actualidad:

  • <Suspense> API para dividir el código con lazy . ( enviado en React 16.6)

    • Como sabrá, ya puede usar este.

  • API de modo concurrente, por ejemplo, createRoot y useTransition . ( disponible en experimental )

    • Solución de compatibilidad para bibliotecas tipo Flux. ( en progreso @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • Cambiar el modelo de prioridades por uno más sensato. ( en progreso @acdlite , https://github.com/facebook/react/pull/18612)

    • Solo permita que finalice la última transición pendiente. ( en progreso @acdlite)

    • API fuera de pantalla (

    • Efectos de fuego al ocultar / mostrar contenido para Suspense

    • Efectos de fuego al ocultar / mostrar contenido para Fuera de pantalla

    • Muestre y oculte los niños del Portal cuando sea necesario

    • Alinear con el trabajo de estandarización en curso para la programación ( no iniciado )

    • Corregir errores importantes conocidos ( en progreso @gaearon y @acdlite)

    • Cambiar la semántica del evento. ( en progreso @sebmarkbage @trueadm)

    • Delegue a las raíces en lugar del documento para permitir una adopción más gradual ( en progreso , @trueadm)

    • Elimine los eventos discretos en la fase de captura.

    • Considere obtener la prioridad predeterminada de event para jugar mejor con el código imperativo.

    • Finalice otras semánticas y valores predeterminados de API. ( no iniciado )

    • Actualización de mecanografía y documentación.

  • Suspensión para la obtención de datos

    • El soporte de bajo nivel para señalar un componente no está listo para renderizarse (técnicamente también está disponible en React estable, pero esta API no se considera estable).

    • El renderizador del servidor elimina inmediatamente los fallbacks de Suspense ( disponible en versiones experimentales)

    • Una solución para casos de uso de GraphQL (Relay Hooks, enviado ).

    • Una solución para casos de uso que no son de GraphQL ( en progreso @sebmarkbage en colaboración con Next.js).

    • Un paquete de integración para dependencias basadas en datos. ( en curso )

    • Finalizar la API de bloques, incluido el contexto.

    • Una solución de almacenamiento en caché genérica. ( no iniciado )

    • Algún tipo de integración de enrutador.

Casi se siente como "Está en producción en Facebook, así que hemos terminado".

Puedo ver cómo podría verse de esta manera, aunque tbh esta lectura es un poco desmoralizante. :-) Hemos estado trabajando sin parar en esto durante todos los últimos meses, y muchos de los aspectos técnicos están terminados o cerca de terminarse. La mayoría de las obras restantes se dividen en dos categorías:

  • Arreglando los defectos que descubrimos en los diseños iniciales antes de cementarlos en una versión estable. Si tuviéramos que publicar lo que tenemos ahora, tendríamos que seguir adelante con cambios importantes en unos pocos meses. Eso solo sería confuso.

  • Compatibilidad del ecosistema y buenos valores predeterminados. No ayuda si lanzamos algo que nadie puede usar hoy porque no funciona con sus bibliotecas o enfoques existentes. Entonces, la mayor parte del trabajo (por ejemplo, compatibilidad con bibliotecas tipo Flux a través de useMutableSource , elegir una mejor semántica de eventos, enviar una estrategia de almacenamiento en caché recomendada) consiste en garantizar que realmente pueda usar lo que publicamos. Esta es una cola larga.

En términos de "puedes usar hoy" ... Técnicamente, puedes usar todo esto hoy. Hacemos. Específicamente, usamos Relay Hooks y Concurrent Mode. Todavía tenemos importantes cambios planificados y problemas conocidos, por lo que el estado actual no cumple con el estándar en el que lo consideraríamos listo para una amplia adopción. Por supuesto, si no le importa que los errores o las API cambien justo en sus manos, puede usar las versiones @experimental como lo hacemos nosotros.

Yo no diría que Facebook está en una posición especial aquí en términos de que "terminamos". Muy por el contrario, no hemos terminado - pero internamente, estamos dispuestos a tolerar la pérdida de clientes y la acumulación en la parte superior de un tren en movimiento, porque eso es lo que sabemos lo que estamos construyendo es sólido. Sin esta intensa comida para perros, las fallas que descubrimos en seis meses tomarían varios años para descubrirlas y rediseñarlas.

En resumen: hay más trabajo por hacer.

@gaearon ¡ Gracias por esta actualización! Y pido disculpas si mi tono fue incorrecto. Admito que estuve un poco frustrado buscando en Twitter durante meses sin encontrar nada. Este aspecto Server renderer immediately flushes Suspense fallbacks (available in experimental releases) parece algo en lo que podría dedicar tiempo al probar esto con Apollo Graphql para nuestra implementación.

Sí, debería estar listo para que los autores de bibliotecas y personas curiosas comiencen a jugar. Las piezas que faltan se refieren principalmente a proporcionar "caminos felices", pero la mayor parte de la tubería debería estar allí.

El renderizador del servidor elimina inmediatamente los fallbacks de Suspense (disponible en versiones experimentales)

¿Dónde puedo leer sobre esto? Esperaba Referencia de API de modo concurrente (experimental), pero no tuve suerte.

Si alguien tiene una demostración que une Next.js, Relay Hooks y el modo concurrente (con SSR), sería increíble. De lo contrario, podría probar suerte si encuentro suficiente documentación.

@CrocoDillon

No hay documentos adicionales sobre SSR, pero se debe principalmente a que es solo un nuevo comportamiento predeterminado.

Si tiene una versión experimental que cada vez que un componente se suspende en el servidor, en su lugar, eliminamos la reserva de Suspense más cercana. Luego, en el cliente, usaría createRoot(node, { hydrate: true }).render(<App />) .

Tenga en cuenta que esto ya habilita todas las nuevas funciones de hidratación. Entonces, por ejemplo, sus límites de Suspense se "adjuntarán" al HTML de respaldo generado por el servidor y luego intentarán renderizarlo por parte del cliente.

También tenga en cuenta que puede comenzar a hidratarse antes de que se cargue toda la aplicación. Cuando se haya cargado <App> , puedes hidratarte. Siempre que los componentes siguientes se suspendan cuando su código no esté listo (similar a lazy). Lo que React haría en este caso es mantener el contenido HTML del servidor pero "adjuntar" el límite de Suspense a él. Cuando los componentes secundarios se cargan, continuará hidratando. Las partes hidratadas se convertirían en eventos interactivos y repetidos.

Probablemente pueda pedirle a @devknoll los próximos intentos / ejemplos de integración. Probablemente tenga algunos.

Puede habilitar el modo concurrente en Next.js instalando react@experimental y react-dom@experimental y agregando lo siguiente a next.config.js

// next.config.js
module.exports = {
  experimental: {
    reactMode: 'concurrent'
  }
}

Aquí está la discusión de Next.js sobre esto: https://github.com/zeit/next.js/discussions/10645

¿Es posible esperar alguna suspensión en la renderización del servidor (para casos como la generación de sitios estáticos, por ejemplo)? Estoy de acuerdo en que usar devoluciones de llamada es un buen valor predeterminado, solo me pregunto si es anulable.

También tenga en cuenta que puede comenzar a hidratarse antes de que se cargue toda la aplicación. Cuándoha cargado, puedes hidratarte. Siempre que los componentes siguientes se suspendan cuando su código no esté listo (similar a lazy). Lo que React haría en este caso es mantener el contenido HTML del servidor pero "adjuntar" el límite de Suspense a él. Cuando los componentes secundarios se cargan, continuará hidratando. Las partes hidratadas se convertirían en eventos interactivos y repetidos.

@gaearon, ¿quiere decir que puede renderizar un componente normalmente en el servidor, pero usar React.lazy en el cliente? Permitiéndole devolver el marcado completo desde el servidor, pero retrasar el análisis y la representación del código del componente en el cliente. ¿El marcado representado por el servidor actúa como reserva de suspenso aquí?

@robrichard En realidad, no lo he probado con React.lazy específicamente (usamos un contenedor diferente en FB y Next también tiene su propia versión) pero espero que así sea como funcionaría. Vale la pena verificar :-) Con ciertas limitaciones, por ejemplo, si actualiza sus accesorios y no hay un rescate de memo anterior, o si actualiza el contexto anterior, tendremos que eliminarlo y mostrar el respaldo porque no sabemos qué hacer con eso.

@gaearon ¿cuál es el estado actual de hidratación parcial? Sé que # 14717 se fusionó, pero dudo que se convierta en algún lanzamiento.

Ha estado activo en cada lanzamiento de @experimental durante mucho tiempo, siempre que use la API unstable_createRoot .

@gaearon , ¿puede explicar qué quiere decir con "dependencias basadas en datos"?

@gaearon , ¿puede explicar qué quiere decir con "dependencias basadas en datos"?

Sí, por supuesto. Debo disculparme por la brevedad de la lista anterior: está muy condensada y muchos de estos son subproyectos separados importantes (por eso están tomando tiempo).

Déjame dar un paso atrás y darte un contexto más amplio antes de responder tu pregunta específica. El contexto más amplio es que crear una solución de obtención de datos realmente buena es muy, muy difícil. No solo en el sentido de la implementación, sino en el sentido del diseño. Por lo general, uno tendría que hacer un compromiso entre la colocación (mantener los requisitos de datos cerca de donde se usan los datos) y la eficiencia (qué tan temprano comenzamos a cargar los datos y podemos evitar las cascadas de red). Esto no es tan notable a pequeña escala, pero a medida que aumenta el número de componentes, realmente debe elegir entre un gran rendimiento y un código fácil de escribir. En muchos casos, desafortunadamente, no obtiene ninguno, razón por la cual la búsqueda de datos en general es un tema tan candente.

Tenemos un listón muy alto para lo que entra en React "oficial". Para ser "Reacty", tiene que componer tan bien como lo hacen los componentes React normales. Esto significa que no podemos recomendar de buena fe una solución que no creemos que pueda escalar a miles de componentes. Tampoco podemos recomendar una solución que lo obligue a escribir código de una manera complicada y optimizada para mantener su rendimiento. En FB, hemos aprendido muchas lecciones al respecto del equipo de relevos. Sabemos que no todo el mundo puede utilizar GraphQL o querría utilizar Relay (no es muy popular en sí mismo y el equipo no lo ha optimizado para su adopción externa). Pero queremos asegurarnos de que nuestra solución de obtención de datos para React general incorpore las lecciones de Relay que tanto

Quiero enfatizar que esto no se trata solo de grandes aplicaciones. Los problemas son más evidentes en las aplicaciones grandes, pero las aplicaciones pequeñas que importan un montón de componentes de npm también sufren de un subconjunto de estas ineficiencias. Como enviar demasiado código del lado del cliente y cargarlo en cascada. O cargar demasiado por adelantado. Además, las aplicaciones pequeñas no se quedan pequeñas para siempre. Queremos una solución que funcione muy bien para una aplicación de cualquier tamaño, al igual que el modelo de componente React funciona de la misma manera independientemente de la complejidad de su aplicación.

Ahora, para abordar su pregunta específica. Relay tiene una función llamada "dependencias controladas por datos". Una forma de pensarlo es una evolución de la dinámica import . Dinámico import no siempre es eficiente. Si desea cargar algún código solo cuando una condición es verdadera (por ejemplo, "el usuario ha iniciado sesión" o "el usuario tiene mensajes no leídos"), su única opción es activarlo de manera perezosa. Pero esto significa que está "iniciando" la búsqueda (como con React.lazy ) solo cuando se usa algo. De hecho, es demasiado tarde. Por ejemplo, si tiene varios niveles de componentes de código dividido (o componentes en espera de datos), el más interno solo comenzará a cargarse después de que se haya cargado el anterior. Esto es ineficiente y es una "cascada" de la red. Las "dependencias controladas por datos" de retransmisión le permiten especificar los módulos que desea obtener como parte de la consulta. Es decir, "si alguna condición es verdadera, incluya este fragmento de código con la respuesta de datos". Esto le permite cargar todos los fragmentos de código dividido que necesitará lo antes posible. No tiene que cambiar la colocación por rendimiento. Esto puede parecer poco importante, pero redujo los segundos literales en el código del producto.

Ahora, nuevamente, no estamos poniendo Relay en React, y no queremos forzar a la gente a usar GraphQL. Pero conceptualmente, la función en sí es genérica, y tener una buena solución de código abierto permitiría a las personas dividir mucho más código de lo que se hace hoy (¡y por lo tanto enviar mucho menos código JS del cliente!). Esa función genérica no se llamará "dependencias controladas por datos": ese es solo un nombre de Relay al que me referí. Esta característica será parte de una solución recomendada más grande que no requiere GraphQL. Solo me referí a él por ese nombre en la lista porque esto era mucho para explicar para un solo punto de lista de viñetas.

Espero que esto lo aclare.

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