Простые и настраиваемые переходы страниц для приложений Next.js
Демо: https://next-page-transitions.now.sh/
Проще говоря, это позволяет легко добавить переходы страниц в приложения, строительные с помощью next.js. Это может работать с другими рамками, но было разработано вокруг нового компонента App и способа, которым следующее. JS обрабатывает страницы. В частности, он решает проблему, чтобы убедиться, что только один компонент страницы устанавливается за раз и что следующая страница не установлена до тех пор, пока предыдущая не завершит свою анимацию выхода. Он также имеет встроенную поддержку для показа индикатора загрузки, если ваш компонент страницы должен загружать данные, прежде чем его можно будет показать.
Если вы предпочитаете учиться примером, ознакомьтесь с каталогом examples для некоторых приложений next.js, которые демонстрируют, как можно использовать эту библиотеку.
Сначала установите пакет:
npm install --save next-page-transitions
Далее, убедитесь, что в вашем приложении есть пользовательский компонент App ; Если нет, следуйте примеру на следующем.js Readme, чтобы создать его. Затем в методе рендеринга вашего App оберните Component страницы в компонент PageTransition . Вам также придется определить свои собственные классы CSS, которые достигают нужных переходных анимаций. Чтобы сохранить эту библиотеку простой и учитывать широкий спектр способов, которыми люди производят и потребляют CSS, она не предлагает никаких встроенных стилей и не имеет особого мнения о том, как стили заканчиваются на вашей странице. Приведенный ниже пример имеет простой переход, который исчезает и выходит страницы.
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 >
)
}
} Когда вы переходите на новую страницу, key опора изменится, и компонент PageTransition обнаружит это. Вместо того, чтобы немедленно отстранить страницу, она будет применять класс page-transition-exit к обертке вокруг страницы, чтобы инициализировать переход «выход», а затем применим класс page-transition-exit-active , а также для начала перехода. Это очень похоже на то, как библиотека группы реагирует в группе. После того, как предыдущая страница была анимирована, новая страница установлена, и будут применяться аналогичная пара классов .page-transition-enter и page-transition-enter-active . Этот процесс повторяется каждый раз, когда новая страница ориентируется.
ПРИМЕЧАНИЕ . В предыдущих версиях next-page-transitions не было необходимости указывать key опору для детей PageTransition . Однако для правильной работы горячего перезагрузки модуля необходимо было сделать эту опору. Перемещение Фоуарда, дети, которые не указывают key опору, вызовут предупреждение в консоли. В будущем это может стать ошибкой времени выполнения.
Предположим, у вас есть страница, которая должна сделать сетевой запрос, прежде чем он сможет отобразить свой контент. Вы могли бы иметь саму страницу, показывающую загрузочную спиннер, пока она не будет готова к работе, но затем вы потеряете прекрасную анимацию перехода на страницу, которую вы потратили все это время, совершенствовавшись. К счастью, эта библиотека позволяет легко справиться с этим случаем.
Если вы добавите статическое свойство pageTransitionDelayEnter = true к компоненту вашей страницы, ваша страница будет передана специальной обратной задачей, которую вы можете использовать, чтобы указать, что все завершило загрузку. В то же время, ваша страница будет установлена, но переход Enter еще не будет запущен, и на его месте будет показан индикатор загрузки по вашему выбору. Когда вы позвоните в обратную опору, загрузка спиннера будет скрыта, и ваша страница будет анимирована на месте! По умолчанию обратный вызов передается через pageTransitionReadyToEnter Prop, но это может быть указано, установив опору на loadingCallbackName на вашем компоненте PageTransition .
ПРИМЕЧАНИЕ. Убедитесь, что ваш компонент возвращает null с функции render() пока не закончит загружать свой контент и будет готов к анимированию. Ваша страница все еще будет в дереве компонентов React во время загрузки!
«Но мои сетевые запросы обычно быстрые!» - скажете вы. «Они обычно занимают всего несколько сотен миллисекунд, и я не хочу прошивать индикатор загрузки на экране в течение такого короткого периода времени!» Эта библиотека также может справиться с этим случаем. Если вы указываете опору loadingDelay , индикатор загрузки не будет показан до тех пор, пока не будет пройдет столько времени. Если ваш компонент готов к входу до этого, индикатор загрузки никогда не будет показан, сохраняя чистый и быстрый UX. Однако, если ваш компонент занимает много времени, индикатор загрузки будет показан до тех пор, пока ваш компонент не будет готов.
«Это звучит как концепция заполнителя из этого разговора о том, что в этом видео на YouTube». Да, да, это так! Это было вдохновением для этой функции.
Вот пример компонента, который имитирует сетевой запрос с тайм -аутом:
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 >
}
} Предположим на мгновение, что у вас есть компонент Loader , который делает хороший индикатор вращения. Вам придется сообщить компоненту PageTransition , что вы хотите использовать этот компонент, и как долго вы хотите подождать, пока не покажут индикатор сети:
<PageTransition
timeout={300}
classNames="page-transition"
loadingComponent={<Loader />}
loadingDelay={500}
loadingTimeout={{
enter: 400,
exit: 0,
}}
loadingClassNames="loading-indicator"
>
<Component {...pageProps} key={router.route} />
</PageTransition>
Вам также придется добавить стили, если вы хотите, чтобы индикатор загрузки был анимирован включен/выключен на экран. Если вы хотите, чтобы он появился/исчезал без какой -либо анимации, вы можете добавить loadingTimeout={0} и опустить свойство loadingClassNames .
Ознакомьтесь с приложением delayed-enter в рамках каталога examples чтобы получить полный пример того, как это выглядит. Страница «О» ( pages/about.js ) будет ждать за 2 секунды, прежде чем отобразить его содержимое, а в то же время будет отображаться компонент на components/Loader.js . Играйте с различными задержками, чтобы получить более глубокое представление о том, как работает этот компонент.
PageTransition реквизитclassNames : указывает имена классов, которые будут применены к обертке страницы, чтобы стимулировать анимации перехода страницы. Аналогично classNames Prop of react-transition-group компонента CSSTranstition . Однако обратите внимание, что в настоящее время поддерживается только строковая форма этой опоры. Кроме того, обратите внимание, что в этой библиотеке нет отдельного «появления» состояния; Необходимы только классы «ввода» и «выхода».tag : указывает тег или компонент, который будет использоваться для отображения обертки страницы. Этот элемент получит classNames опору. Это полезно, если вы хотите использовать семантическую разметку, например, если вы хотите отображать обертку страницы в качестве main , или если вам нужно дополнительно настроить стиль или поведение обертки страницы.timeout : указывает тайм -ауты для анимации перехода страниц. Аналогично timeout предложению компонента CSSTranstition react-transition-group .loadingComponent : элемент реагирования должен быть показан во времяloadingDelay : продолжительность ожидания перед тем, как показать индикатор загрузки в миллисекундах. Если страница заканчивает загрузку до того, как эта продолжительность истекла, компонент загрузки никогда не будет показан. По умолчанию до 500 мс.loadingCallbackName : указывает имя опоры, которую ваша страница будет получать, чтобы позвонить, когда она будет выполнена. По умолчанию в pageTransitionReadyToEnterloadingTimeout : аналогично timeout интерфейсу компонента CSSTranstition react-transition-group . Если эта опора установлена на 0 , индикатор загрузки не будет анимирован включен/выключен на экран.loadingClassNames : указывает имена классов, которые будут применены к компоненту загрузки, если он будет указан. Аналогично classNames Prop of react-transition-group компонента CSSTranstition .monkeyPatchScrolling : По умолчанию компонент Link Next будет прокручиваться в верхней части страницы всякий раз, когда она нажимается; Это может иметь нежелательный прыжковой эффект, когда страница переходит. Если эта опора установлена на true , когда компонент установлен, то window.scrollTo будет переоборудовано обезьян, так что программная прокрутка может быть отключена при переходе страницы. По умолчанию ложно, поскольку это потенциально отрывочное поведение должно быть внесено в действие.skipInitialTransition : указывает, будет ли переход страницы будет опущен на первом креплении. Если вы хотите иметь переходы только между страницами, а не на загрузке первой страницы, установите skipInitialTransition на true . По умолчанию skipInitialTransition установлено на false .PRS приветствуются! Прежде чем работать и отправить PR, пожалуйста, задайте проблему, описывающую функцию, которую вы хотите построить. Это может быть за пределами масштаба этого проекта, иначе, или сопровождающий, возможно, уже работает над ним.