I'm using the new _app.js
file for Next.js to try and create a page transition such as a fade or slide but can't get my head around it. I'm using Styled Components to apply the styling. My structure looks like this currently:
_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;
components/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;
components/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;
Would this be a correct approach? If so, I don't think componentDidUpdate is soon enough to catch the page change. My attempts at this work but it does a render and you see a flash of the page before the state updates again to tell it to start the fade out then fade in. I would need to update the state before the render.
Is there a way to handle this with React Transition Group? I did look at next-page-transitions but wasn't comfortable that the package has low usage and I just wanted a simpler solution.