Transiciones de página simples y personalizables para aplicaciones Next.js
Demo: https://next-page-transitions.now.sh/
En pocas palabras, facilita agregar transiciones de página a las aplicaciones Build con Next.js. Puede funcionar con otros marcos, pero fue diseñado alrededor del nuevo componente App y la forma en que Next.js maneja las páginas. Específicamente, resuelve el problema de asegurarse de que solo un componente de una página esté montado a la vez y que la página siguiente no esté montada hasta que la anterior haya completado su animación de salida. También tiene soporte incorporado para mostrar un indicador de carga si el componente de su página tiene que cargar datos antes de que se pueda mostrar.
Si prefiere aprender con el ejemplo, consulte el directorio examples para algunas aplicaciones Next.js que demuestren cómo se puede usar esta biblioteca.
Primero, instale el paquete:
npm install --save next-page-transitions
A continuación, asegúrese de que su aplicación tenga un componente App personalizado; Si no, siga el ejemplo en la lectura siguiente.js para crear uno. Luego, en el método de renderizado de su App , envuelva el Component de la página en un componente PageTransition . También tendrá que definir sus propias clases CSS que logren las animaciones de transición que desea. Para mantener esta biblioteca simple y tener en cuenta la amplia variedad de formas en que las personas producen y consumen CSS, no ofrece ningún estilos incorporados y no tiene una opinión particular sobre cómo terminan los estilos en su página. El ejemplo a continuación tiene una transición simple que se desvanece dentro y fuera.
import App , { Container } from 'next/app'
import React from 'react'
import { PageTransition } from 'next-page-transitions'
export default class MyApp extends App {
static async getInitialProps ( { Component , router , ctx } ) {
let pageProps = { }
if ( Component . getInitialProps ) {
pageProps = await Component . getInitialProps ( ctx )
}
return { pageProps }
}
render ( ) {
const { Component , pageProps , router } = this . props
return (
< Container >
< PageTransition timeout = { 300 } classNames = "page-transition" >
< Component { ... pageProps } key = { router . route } />
</ PageTransition >
< style jsx global > { `
.page-transition-enter {
opacity: 0;
}
.page-transition-enter-active {
opacity: 1;
transition: opacity 300ms;
}
.page-transition-exit {
opacity: 1;
}
.page-transition-exit-active {
opacity: 0;
transition: opacity 300ms;
}
` } </ style >
</ Container >
)
}
} Cuando se mueve a una nueva página, el accesorio key cambiará y el componente PageTransition lo detectará. En lugar de desmontar inmediatamente la página, aplicará la clase page-transition-exit a un envoltorio alrededor de la página para inicializar la transición "Salir", y luego aplicará la clase page-transition-exit-active también para comenzar la transición. Esto es muy similar a cómo la biblioteca React-Transition-Group hace las cosas. Después de que la página anterior se ha animado, la nueva página está montada y page-transition-enter-active aplicarán un par de .page-transition-enter . Este proceso se repite cada vez que se navega una nueva página.
Nota : En versiones anteriores de next-page-transitions , no fue necesario especificar el accesorio key en los niños de PageTransition . Sin embargo, para hacer que la recarga del módulo caliente funcione correctamente, era necesario hacer que este apoyo fuera necesario. Mover Foward, los niños que no especifican un accesorio key activarán una advertencia en la consola. En el futuro, esto puede convertirse en un error de tiempo de ejecución.
Supongamos que tiene una página que necesita hacer una solicitud de red antes de que pueda mostrar su contenido. Podría tener la página en sí renderizando una ruleta de carga hasta que esté lista para comenzar, pero luego pierde la hermosa animación de transición de la página que pasaste todo el tiempo perfeccionando. Afortunadamente, esta biblioteca facilita el manejo de ese caso.
Si agrega una propiedad estática pageTransitionDelayEnter = true al componente de su página, su página se pasará por un accesorio especial de devolución de llamada que puede usar para indicar que todo ha terminado de cargar. Mientras tanto, su página se montará, pero la transición Enter aún no se iniciará, y un indicador de carga de su elección se mostrará en su lugar. Cuando llame al accesorio de devolución de llamada, el spinner de carga estará oculto y su página se animará en su lugar. De manera predeterminada, la devolución de llamada se pasa a través del accesorio pageTransitionReadyToEnter , pero esto se puede especificar configurando el accesorio loadingCallbackName en su componente PageTransition .
Nota: Asegúrese de que su componente devuelva null de su función render() hasta que haya terminado de cargar su contenido y esté listo para ser animado. ¡Su página aún estará en el árbol de componentes React mientras se carga!
"¡Pero mis solicitudes de red suelen ser rápidas!", Dirás. "Por lo general, solo toman unos pocos cientos de milisegundos, ¡y no quiero flashear un indicador de carga en la pantalla por un período de tiempo tan corto!" Esta biblioteca también puede manejar ese caso. Si especifica un accesorio loadingDelay , el indicador de carga no se mostrará hasta que haya transcurrido ese tiempo. Si su componente está listo para ingresar antes, el indicador de carga nunca se mostrará, manteniendo el UX limpio y ágil. Sin embargo, si su componente está tomando mucho tiempo, el indicador de carga se mostrará hasta que su componente esté listo.
"Eso suena como el concepto de marcador de posición de esa charla de suspenso de reaccionamiento. El que está en este video de YouTube". ¡Sí, sí, lo hace! Esa fue la inspiración para esta característica.
Aquí hay un componente de ejemplo que simula una solicitud de red con un tiempo de espera:
class About extends React . Component {
static pageTransitionDelayEnter = true
constructor ( props ) {
super ( props )
this . state = { loaded : false }
}
componentDidMount ( ) {
this . timeoutId = setTimeout ( ( ) => {
this . props . pageTransitionReadyToEnter ( )
this . setState ( { loaded : true } )
} , 2000 )
}
componentWillUnmount ( ) {
if ( this . timeoutId ) clearTimeout ( this . timeoutId )
}
render ( ) {
if ( ! this . state . loaded ) return null
return < div > Hello, world! </ div >
}
} Suponga por un momento que tiene un componente Loader que hace un buen indicador de carga giratoria. Tendrá que decirle al componente PageTransition que desea usar este componente y cuánto tiempo desea esperar hasta que muestre el indicador de red:
<PageTransition
timeout={300}
classNames="page-transition"
loadingComponent={<Loader />}
loadingDelay={500}
loadingTimeout={{
enter: 400,
exit: 0,
}}
loadingClassNames="loading-indicator"
>
<Component {...pageProps} key={router.route} />
</PageTransition>
También tendrá que agregar estilos si desea que el indicador de carga se anime encendido/apagado de la pantalla. Si desea que aparezca/desaparezca sin ninguna animación, puede agregar loadingTimeout={0} y omitir la propiedad loadingClassNames .
Consulte la aplicación delayed-enter en el directorio examples para obtener un ejemplo completo de cómo se ve esto. La página "Acerca de" ( pages/about.js ) esperará 2 segundos antes de mostrar su contenido, y mientras tanto, se mostrará el componente en components/Loader.js . Juega con los diversos retrasos para obtener una sensación más profunda de cómo funciona este componente.
PageTransitionclassNames : especifica los nombres de clase que se aplicarán al envoltorio de página para impulsar las animaciones de transición de la página. Análogo al accesorio classNames del componente CSSTranstition del react-transition-group . Sin embargo, tenga en cuenta que solo la forma de cadena de ese accesorio se admite en la actualidad. Además, tenga en cuenta que esta biblioteca no tiene un estado de "aparición" separado; Solo se necesitan clases de "ingresar" y "salir".tag : Especifica la etiqueta o componente que se utilizará para representar el envoltorio de página. Este elemento recibirá el classNames . Esto es útil si desea utilizar el marcado semántico, por ejemplo, si desea representar el envoltorio de página como main , o si necesita personalizar aún más el estilo o el comportamiento del envoltorio de página.timeout : Especifica tiempos de espera para las animaciones de transición de la página. Análogo al accesorio timeout del componente CSSTranstition del react-transition-group .loadingComponent : un elemento react que se mostrará mientrasloadingDelay : la duración de esperar antes de mostrar el indicador de carga, en milisegundos. Si una página finaliza la carga antes de que haya transcurrido esta duración, el componente de carga nunca se mostrará. El valor predeterminado a 500 ms.loadingCallbackName : especifica el nombre del accesorio que su página recibirá para llamar cuando haya terminado de cargar. El valor predeterminado a pageTransitionReadyToEnterloadingTimeout : análogo al accesorio timeout del componente CSSTranstition del react-transition-group . Si este accesorio se establece en 0 , el indicador de carga no se animará encendido/apagado de la pantalla.loadingClassNames : especifica los nombres de clase que se aplicarán al componente de carga si se especifica uno. Análogo al accesorio classNames del componente CSSTranstition del react-transition-group .monkeyPatchScrolling : de forma predeterminada, el componente Link del próximo se desplazará a la parte superior de la página siempre que se haga clic; Esto puede tener un efecto nervioso indeseable cuando una página está en transición. Si este accesorio se establece en true cuando se monta el componente, entonces window.scrollTo estará empapado de mono para que el desplazamiento programático se pueda deshabilitar mientras una página está en transición. El valor predeterminado es FALSO, ya que este comportamiento potencialmente incompleto debe ser optada.skipInitialTransition : especifica si la transición de la página se omitirá en el primer soporte. Si desea tener transiciones solo entre páginas, no en la carga de la primera página, establezca skipInitialTransition en true . Por defecto, skipInitialTransition se establece en false .¡PRS son bienvenidos! Antes de trabajar y enviar un PR, haga un problema que describa la función que desea construir. Puede estar fuera del alcance de este proyecto, o un mantenedor podría estar trabajando en él.