![](/img/trans.png)
[英]How to play a CSS animation on every page transition with Next.js?
[英]Next.js page transition
我正在使用_app.js
的新_app.js
文件來嘗試創建頁面過渡,例如淡入淡出或幻燈片,但無法理解它。 我正在使用樣式化組件來應用樣式。 我的結構目前是這樣的:
_app.js
import App, { Container } from 'next/app';
import React from 'react';
import PageTransition from '../components/PageTransition';
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
}
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<PageTransition>
<Component {...pageProps} />
</PageTransition>
</Container>
);
}
}
export default MyApp;
組件/PageTransition/index.jsx
import { Transition } from 'react-transition-group';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Root from './index.style';
class PageTransition extends Component {
state = {
active: true,
}
componentDidUpdate() {
// Check if children are different to previous children
// If true, set this.state.active to false
// After 1000ms transition, set to true again
}
render() {
const { children } = this.props;
const { active } = this.state;
return (
<Transition in timeout={1000}>
<Root id="root" active={active}>
{children}
</Root>
</Transition>
);
}
}
export default PageTransition;
組件/PageTransition/index.style.js
import styled from 'styled-components';
const Root = styled.div`
opacity: ${p => (p.active ? 1 : 0)};
transition: opacity 1000ms;
`;
export default Root;
這是一個正確的方法嗎? 如果是這樣,我認為 componentDidUpdate 還不足以趕上頁面更改。 我對這項工作的嘗試,但它進行了渲染,您會在狀態再次更新之前看到頁面閃爍,告訴它開始淡出然后淡入。我需要在渲染之前更新狀態。
有沒有辦法用 React Transition Group 來處理這個問題? 我確實查看了next-page-transitions,但對該包的使用率低感到不舒服,我只是想要一個更簡單的解決方案。
我最近也在研究如何實現這一點。 查看下一頁過渡的簡要文檔,實現簡單的淡入/淡出頁面過渡就像在 App 組件渲染方法中使用它一樣簡單:
render() {
const { Component, pageProps } = this.props
return (
<Container>
<PageTransition timeout={300} classNames="page-transition">
<Component {...pageProps} />
</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>
)
}
但是,我看到您正在嘗試使用 react-transition-group。 如果您希望實現更復雜的動畫,這就是您想要使用的庫。
這是我使用 react-transition-group 進行的快速測試的 App 組件渲染方法的示例:
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<div ref={x => (this.comp = x)}>
<TransitionGroup>
<Transition
in={this.props.in}
key={this.props.router.route}
timeout={{
enter: 2000,
exit: 2000
}}
mountOnEnter={false}
unmountOnExit={true}
onEnter={this.enterTransition}
>
<Component {...pageProps} />
</Transition>
</TransitionGroup>
</div>
</Container>
);
}
注意:我使用 GSAP 制作動畫,在我所做的這個測試中,我需要在初始安裝時引用組件的內容。 如果你不需要這個,那么你可以去掉那個 div,然后確保為 onEnter 提供一個將在每個頁面導航時調用的函數。
enterTransition = node => {
TweenMax.fromTo(node, 0, { x: 0, opacity: 0 }, {x: 200, opacity: 1});
}
該節點將是下一個要掛載的組件。 還有一個 onExit 鈎子,您可以使用它以類似的方式定位退出節點。
我對這項工作的嘗試,但它進行了渲染,您會在狀態再次更新之前看到頁面閃爍,告訴它開始淡出然后淡入。我需要在渲染之前更新狀態。
這個問題可以通過將display: none
默認放在你的組件上來解決,然后一旦頁面完全呈現,顯示它並在需要時應用動畫
使用key
....
只有當route
發生變化時, Key
才會觸發頁面更改轉換。
你可以這樣做:
render() {
const { Component, pageProps, router } = this.props;
return (
<Container>
<PageTransition>
<Component {...pageProps} key={router.route} />
</PageTransition>
</Container>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.