Transitions de page simples et personnalisables pour les applications Next.js
Demo: https://next-page-transition.now.sh/
Autrement dit, il est facile d'ajouter des transitions de page aux applications Build avec next.js. Il peut fonctionner avec d'autres cadres, mais il a été conçu autour du nouveau composant App et de la façon dont Next.js gère les pages. Plus précisément, il résout le problème de s'assurer qu'un seul composant de page est monté à la fois et que la page suivante n'est pas montée jusqu'à ce que la précédente ait terminé son animation de sortie. Il a également une prise en charge intégrée pour afficher un indicateur de chargement si votre composant de page doit charger des données avant de pouvoir être affichée.
Si vous préférez apprendre par exemple, consultez le répertoire examples pour certaines applications Next.js qui montrent comment cette bibliothèque peut être utilisée.
Tout d'abord, installez le package:
npm install --save next-page-transitions
Ensuite, assurez-vous que votre application dispose d'un composant App personnalisé; Sinon, suivez l'exemple sur la lecture Next.js pour en créer une. Ensuite, dans la méthode de rendu de votre App , enveloppez le Component de page dans un composant PageTransition . Vous devrez également définir vos propres classes CSS qui réalisent les animations de transition que vous souhaitez. Pour garder cette bibliothèque simple et pour tenir compte de la grande variété de façons dont les gens produisent et consomment CSS, il n'offre aucun styles intégrés et n'a aucune opinion particulière sur la façon dont les styles se retrouvent sur votre page. L'exemple ci-dessous a une transition simple qui atténue les pages à l'intérieur et à l'extérieur.
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 >
)
}
} Lorsque vous passez à une nouvelle page, l'hélice key changera et le composant PageTransition détectera cela. Au lieu de défaut immédiatement la page, il appliquera la classe page-transition-exit à un wrapper autour de la page pour initialiser la transition "Exit", et appliquera ensuite la classe page-transition-exit-active également pour commencer la transition. Ceci est très similaire à la façon dont la bibliothèque de groupes React-Transition-Groupe fait les choses. Une fois que la page précédente a été animée, la nouvelle page est montée et une paire similaire de classes. .page-transition-enter et page-transition-enter-active sera appliquée. Ce processus se répète chaque fois qu'une nouvelle page est navigue.
Remarque : Dans les versions précédentes des next-page-transitions , il n'était pas nécessaire de spécifier l'hélice key sur les enfants PageTransition . Cependant, pour faire fonctionner correctement le rechargement du module chaud, il était nécessaire de rendre cet accessoire requis. Déplacement de Foward, les enfants qui ne spécifient pas un accessoire key déclenchent un avertissement dans la console. À l'avenir, cela pourrait devenir une erreur d'exécution.
Supposons que vous ayez une page qui doit faire une demande réseau avant de pouvoir afficher son contenu. Vous pourriez demander à la page elle-même de rendre un spinner de chargement jusqu'à ce qu'il soit prêt à partir, mais vous perdez ensuite la belle animation de transition de page que vous avez passé tout ce temps à perfectionner. Heureusement, cette bibliothèque facilite la gestion de cette affaire.
Si vous ajoutez une propriété statique pageTransitionDelayEnter = true to Your Page Component, votre page sera transmise un accessoire de rappel spécial que vous pouvez utiliser pour indiquer que tout a terminé le chargement. En attendant, votre page sera montée, mais la transition ENTER ne sera pas encore lancée, et un indicateur de chargement de votre choix sera affiché à sa place. Lorsque vous appelez l'hélice de rappel, le spinner de chargement sera caché et votre page sera animée en place! Par défaut, le rappel est passé via l'hélice pageTransitionReadyToEnter , mais cela peut être spécifié en définissant l'hélice loadingCallbackName sur votre composant PageTransition .
Remarque: assurez-vous que votre composant renvoie null de sa fonction render() jusqu'à ce qu'il ait fini de charger son contenu et est prêt à être animé. Votre page sera toujours dans l'arborescence des composants React pendant qu'il se charge!
"Mais mes demandes de réseau sont généralement rapides!", Disrez-vous. "Ils ne prennent généralement que quelques centaines de millisecondes, et je ne veux pas flasher un indicateur de chargement sur l'écran pendant une si courte période!" Cette bibliothèque peut également gérer cette affaire. Si vous spécifiez un accessoire loadingDelay , l'indicateur de chargement ne sera pas affiché tant que beaucoup de temps s'est écoulé. Si votre composant est prêt à entrer avant cela, l'indicateur de chargement ne sera jamais affiché, en gardant l'UX propre et raccourci. Cependant, si votre composant prend beaucoup de temps, l'indicateur de chargement sera affiché jusqu'à ce que votre composant soit prêt.
"Cela ressemble un peu à ce que le concept d'espace réservé de cette conversation de suspense réagit. Celui de cette vidéo YouTube." Oui, oui c'est le cas! C'était l'inspiration pour cette fonctionnalité.
Voici un exemple de composant qui simule une demande de réseau avec un délai d'expiration:
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 >
}
} Supposons un instant que vous avez un composant Loader qui rend un bel indicateur de chargement de rotation. Vous devrez dire au composant PageTransition que vous souhaitez utiliser ce composant et combien de temps vous souhaitez attendre jusqu'à afficher l'indicateur de réseau:
<PageTransition
timeout={300}
classNames="page-transition"
loadingComponent={<Loader />}
loadingDelay={500}
loadingTimeout={{
enter: 400,
exit: 0,
}}
loadingClassNames="loading-indicator"
>
<Component {...pageProps} key={router.route} />
</PageTransition>
Vous devrez également ajouter des styles si vous souhaitez que l'indicateur de chargement soit animé sur / hors de l'écran. Si vous voulez qu'il apparaisse / disparaît sans aucune animation, vous pouvez ajouter loadingTimeout={0} et omettre la propriété loadingClassNames .
Consultez l'application delayed-enter dans le répertoire examples pour un exemple complet de ce à quoi cela ressemble. La page "À propos" ( pages/about.js ) attendra 2 secondes avant d'afficher son contenu, et en attendant, le composant de components/Loader.js sera affiché. Jouez avec les différents retards pour mieux comprendre le fonctionnement de ce composant.
PageTransitionclassNames : Spécifie les noms de classe qui seront appliqués au wrapper de la page pour piloter les animations de transition de page. Analogue avec l'hélice classNames du composant CSSTranstition du react-transition-group . Cependant, notez que seule la forme de chaîne de cet accessoire est actuellement prise en charge. Notez également que cette bibliothèque n'a pas d'état "Apparation" séparé; Seules les classes "Entrée" et "Exit" sont nécessaires.tag : spécifie la balise ou le composant qui sera utilisé pour rendre le wrapper de la page. Cet élément recevra l'hélice classNames . Ceci est utile si vous souhaitez utiliser le balisage sémantique, par exemple si vous souhaitez rendre l'emballage de la page comme main , ou si vous devez personnaliser davantage le style ou le comportement de l'emballage de la page.timeout : Spécifie les délais d'expiration des animations de transition de page. Analogue à l'hélice timeout du composant CSSTranstition du react-transition-group .loadingComponent : un élément de réact à afficherloadingDelay : la durée à attendre avant de montrer l'indicateur de chargement, en millisecondes. Si une page termine le chargement avant que cette durée ne se soit écoulée, le composant de chargement ne sera jamais affiché. Par défaut à 500 ms.loadingCallbackName : Spécifie le nom de l'hélice que votre page recevra à appeler lorsqu'il sera terminé le chargement. Par défaut à pageTransitionReadyToEnterloadingTimeout : analogue à l'hélice timeout du composant CSSTranstition du react-transition-group . Si cet accessoire est défini sur 0 , l'indicateur de chargement ne sera pas animé sur / hors de l'écran.loadingClassNames : spécifie les noms de classe qui seront appliqués au composant de chargement si l'on est spécifié. Analogue avec l'hélice classNames du composant CSSTranstition du react-transition-group .monkeyPatchScrolling : Par défaut, le composant Link de Next défilera en haut de la page chaque fois qu'il est cliqué; Cela peut avoir un effet nerveux indésirable lorsqu'une page est en train de passer. Si cet accessoire est défini sur true lorsque le composant est monté, alors window.scrollTo sera apparié de singe afin que le défilement programmatique puisse être désactivé pendant une page en transition. Par défaut est faux, car ce comportement potentiellement sommaire devrait être opt.skipInitialTransition : Spécifie si la transition de la page sera omise lors du premier montage. Si vous voulez avoir des transitions uniquement entre les pages, et non sur la première page, définissez skipInitialTransition vers true . Par défaut, skipInitialTransition est défini sur false .Les PR sont les bienvenus! Avant de travailler sur et de soumettre un PR, veuillez faire un problème décrivant la fonctionnalité que vous souhaitez créer. Il peut être en dehors du champ d'application de ce projet, ou un responsable peut déjà y travailler.