Einfache und anpassbare Seitenübergänge für Next.js Apps
Demo: https://next-page-transitions.now.sh/
Einfach ausgedrückt, erleichtert es einfach, Seitenübergänge zu Apps Build mit Next.js. hinzuzufügen. Es kann mit anderen Frameworks funktionieren, wurde jedoch um die neue App -Komponente und die Art und Weise entwickelt, wie es als nächstes.js mit Seiten umgeht. Insbesondere löst es das Problem, sicherzustellen, dass jeweils nur eine Seitenkomponente montiert ist und dass die nächste Seite erst dann montiert ist, wenn die vorherige seine Exit -Animation abgeschlossen hat. Es wird auch integriert, um eine Ladeanzeige anzuzeigen, wenn Ihre Seitenkomponente Daten laden muss, bevor diese angezeigt werden können.
Wenn Sie es lieber mit Beispiel lernen, lesen Sie das examples -Verzeichnis für einige Next.js -Apps, die zeigen, wie diese Bibliothek verwendet werden kann.
Installieren Sie zunächst das Paket:
npm install --save next-page-transitions
Stellen Sie als nächstes sicher, dass Ihre App eine benutzerdefinierte App -Komponente hat. Wenn nicht, befolgen Sie das Beispiel im nächsten.js Readme, um eine zu erstellen. Wickeln Sie dann nach der Render -Methode Ihrer App die Component in eine PageTransition -Komponente ein. Sie müssen auch Ihre eigenen CSS -Klassen definieren, die die gewünschten Übergangsanimationen erreichen. Um diese Bibliothek einfach zu halten und die Vielzahl von Möglichkeiten zu berücksichtigen, wie Menschen CSS produzieren und konsumieren, bietet sie keine integrierten Stile und hat keine besondere Meinung darüber, wie die Stile auf Ihrer Seite landen. Das folgende Beispiel hat einen einfachen Übergang, der die Seiten ein- und ausblendt.
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 >
)
}
} Wenn Sie zu einer neuen Seite wechseln, ändert sich die key Requisite, und die PageTransition -Komponente erkennt dies. Anstatt die Seite sofort zu enttäuschen, wird die Klasse der page-transition-exit auf die Seite auf der Seite angewendet, um den Übergang "Beenden" zu initialisieren, und wendet dann auch die page-transition-exit-active Klasse an, um den Übergang zu beginnen. Dies ähnelt sehr ähnlich zu der Art und Weise, wie die Bibliothek der React-Übergangsgruppe Dinge tut. Nachdem die vorherige Seite animiert wurde, ist die neue Seite montiert und es wird ein ähnliches Paar von .page-transition-enter und page-transition-enter-active angewendet. Dieser Vorgang wiederholt sich jedes Mal, wenn eine neue Seite navigiert wird.
Hinweis : In früheren Versionen von next-page-transitions war es nicht erforderlich, die key Requisitin für Kinder der PageTransition anzugeben. Um das Nachladen von Hot Modul jedoch korrekt zu laden, war es erforderlich, diese Requisite erforderlich zu machen. Wenn Sie Foward bewegen, werden Kinder, die keine key Requisite angeben, eine Warnung in der Konsole auslöst. In Zukunft könnte dies zu einem Laufzeitfehler werden.
Angenommen, Sie haben eine Seite, auf der eine Netzwerkanforderung gestellt werden muss, bevor sie den Inhalt anzeigen kann. Sie könnten die Seite selbst einen Ladespinner machen, bis sie bereit ist, aber dann verlieren Sie die schöne Seitenübergangsanimation, die Sie die ganze Zeit perfektioniert haben. Zum Glück erleichtert diese Bibliothek es einfach, diesen Fall zu bewältigen.
Wenn Sie eine statische Eigenschaft pageTransitionDelayEnter = true zu Ihrer Seitenkomponente hinzufügen, wird Ihre Seite an einer speziellen Rückrufpropie übergeben, mit der Sie angeben können, dass alles das Laden beendet ist. In der Zwischenzeit wird Ihre Seite montiert, aber der Eingabeteiler wird noch nicht gestartet, und an seiner Stelle wird ein Ladeindikator für Ihre Wahl angezeigt. Wenn Sie die Callback -Requisite anrufen, wird der Ladespinner versteckt und Ihre Seite wird animiert! Standardmäßig wird der Rückruf über die pageTransitionReadyToEnter -Requisite übergeben. Dies kann jedoch angegeben werden, indem die loadingCallbackName -Prop auf Ihre PageTransition -Komponente festgelegt wird.
HINWEIS: Stellen Sie sicher, dass Ihre Komponente null aus seiner Funktion render() zurückgibt, bis sie das Laden ihres Inhalts beendet hat und bereit ist, sich einzuziehen. Ihre Seite befindet sich immer noch im React -Komponentenbaum, während sie geladen wird!
"Aber meine Netzwerkanfragen sind normalerweise schnell!", Sagen Sie. "Normalerweise nehmen sie nur ein paar hundert Millisekunden ein und ich möchte für so kurze Zeit keinen Ladeindikator auf dem Bildschirm blinken!" Diese Bibliothek kann auch diesen Fall bewältigen. Wenn Sie eine loadingDelay -Requisit angeben, wird der Ladeanzeige nicht angezeigt, wenn so viel Zeit vergangen ist. Wenn Ihre Komponente zuvor eingetragen ist, wird die Ladeanzeige niemals angezeigt, sodass die UX sauber und bissig hält. Wenn Ihre Komponente jedoch lange dauert, wird die Ladeanzeige angezeigt, bis Ihre Komponente fertig ist.
"Das klingt nach dem Platzhalterkonzept aus diesem React Spannungsgespräch. Das in diesem YouTube -Video." Ja, ja! Das war die Inspiration für dieses Feature.
Hier ist eine Beispielkomponente, die eine Netzwerkanforderung mit einer Zeitüberschreitung simuliert:
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 >
}
} Nehmen wir für einen Moment an, dass Sie eine Loader haben, die einen schönen Spinn -Ladeindikator macht. Sie müssen die PageTransition -Komponente mitteilen, dass Sie diese Komponente verwenden möchten, und wie lange Sie warten möchten, bis Sie den Netzwerkanzeigen anzeigen:
<PageTransition
timeout={300}
classNames="page-transition"
loadingComponent={<Loader />}
loadingDelay={500}
loadingTimeout={{
enter: 400,
exit: 0,
}}
loadingClassNames="loading-indicator"
>
<Component {...pageProps} key={router.route} />
</PageTransition>
Sie müssen auch Stile hinzufügen, wenn Sie möchten, dass der Ladeindikator ein/aus dem Bildschirm animiert wird. Wenn Sie möchten, dass es ohne Animation aussieht/verschwindet, können Sie loadingTimeout={0} hinzufügen und die Eigenschaft loadingClassNames weglassen.
Schauen Sie sich die delayed-enter App-App unter dem examples an, um ein vollständiges Beispiel dafür zu erhalten, wie dies aussieht. Die "Über" -Seite ( pages/about.js ) wartet 2 Sekunden vor dem Anzeigen des Inhalts, und in der Zwischenzeit wird die Komponente bei components/Loader.js angezeigt. Spielen Sie mit den verschiedenen Verzögerungen, um ein tieferes Gefühl dafür zu gewinnen, wie diese Komponente funktioniert.
PageTransitionclassNames : Gibt die Klassennamen an, die auf den Seitenwrapper angewendet werden, um die Seitenübergangsanimationen zu fahren. Analog zu der classNames CSSTranstition Komponente von react-transition-group von React-Transition-Group. Beachten Sie jedoch, dass derzeit nur die Stringform dieser Requisite unterstützt wird. Beachten Sie auch, dass diese Bibliothek keinen separaten "erscheinen" Zustand hat. Es sind nur "Eingeben "- und" Exit "-Kurs erforderlich.tag : Gibt das Tag oder die Komponente an, mit der die Seitenwrapper gerendert wird. Dieses Element erhält die classNames -Prop. Dies ist nützlich, wenn Sie semantisches Markup verwenden möchten, z. B. wenn Sie den Seitenwrapper als main rendern oder das Styling oder das Verhalten der Seitenwrapper weiter anpassen müssen.timeout : Gibt Timeouts für die Seitenübergangsanimationen an. Analog zu der timeout Requisit der CSSTranstition -Komponente von react-transition-group .loadingComponent : Ein React -Element, das gezeigt werden soll, währendloadingDelay : Die Dauer wartet in Millisekunden, bevor die Ladeanzeige angezeigt wird. Wenn eine Seite vor Ablauf dieser Dauer geladen wird, wird die Ladekomponente niemals angezeigt. Standardeinstellungen zu 500 ms.loadingCallbackName : Gibt den Namen der Requisite an, die Ihre Seite beim Laden anrufen kann. Standardeinstellungen zum pageTransitionReadyToEnterloadingTimeout : Analog zur timeout Requisite der CSSTranstition -Komponente von react-transition-group . Wenn diese Requisite auf 0 gesetzt ist, wird der Ladeanzeigen nicht ein/aus dem Bildschirm animiert.loadingClassNames : Gibt die Klassennamen an, die auf die Ladekomponente angewendet werden, wenn einer angegeben ist. Analog zu der classNames CSSTranstition Komponente von react-transition-group von React-Transition-Group.monkeyPatchScrolling : Standardmäßig scrollt die Link von Next, wenn sie klicken. Dies kann einen unerwünschten, kurzen Effekt haben, wenn eine Seite übergeht. Wenn diese Requisite auf true gesetzt ist, wenn die Komponente montiert ist, wird das window.scrollTo . Standardeinstellungen zu False, da dieses potenziell skizzenhafte Verhalten abgelehnt werden sollte.skipInitialTransition : Gibt an, ob der Seitenübergang am ersten Mount weggelassen wird. Wenn Sie über Übergänge nur zwischen Seiten und nicht auf der ersten Seite geladen möchten, setzen Sie skipInitialTransition auf true . Standardmäßig ist skipInitialTransition auf false festgelegt.PRs sind willkommen! Bevor Sie an einer PR arbeiten und ein PR einreichen, beschreiben Sie bitte ein Problem, in dem die Funktion beschrieben wird, die Sie erstellen möchten. Es kann außerhalb des Rahmens dieses Projekts liegen, oder ein Betreuer arbeitet möglicherweise bereits daran.