illinois / next-page-transitions

Simple and customizable page transitions for Next.js apps
MIT License
548 stars 44 forks source link

Not working with Dynamic Routing #41

Open alenart91 opened 5 years ago

alenart91 commented 5 years ago

Wrapping the component in _app.js with the page transition component throws an error once you try to navigate anywhere from a post using dynamic routing. Using the most basic form from the example without any styling.

import React from 'react';
import App, { Container } from 'next/app';
import { PageTransition } from 'next-page-transitions';

class MyApp extends App {
  // Only uncomment this method if you have blocking data requirements for
  // every single page in your application. This disables the ability to
  // perform automatic static optimization, causing every page in your app to
  // be server-side rendered.

  // static async getInitialProps({ Component, ctx }) {
  //   let pageProps = {}
  //   console.log('hello');
  //
  //   if (Component.getInitialProps) {
  //     pageProps = await Component.getInitialProps(ctx)
  //   }
  //
  //   return { pageProps }
  // }

  render() {
    const { Component, pageProps, router } = this.props;
    console.log('_app', router);
    return (
      <Container>
       <PageTransition timeout={300} classNames="page-transition">
        <Component {...pageProps} key={ router.route }/>
      </PageTransition>

      </Container>
    );
  }
}

export default MyApp;

Here's an example of my blog page using the dynamic routing links

import Link from 'next/link';

function BlogPosts(props) {

  const blogImg = {
    backgroundImage: `url("${props.imgSrc}")`
  };

  if(props.homePage) {
  return(
    <React.Fragment>
    <div className ="blog-post-wrapper">
      <div className ="blog-pic" style = {blogImg}></div>
      <div className ="blog-text-container">
      <h3>{props.postTitle}</h3>
      <p>{props.postPreview}</p>
      <Link href = '/blog/[posts]' as = {`/blog/${props.postSlug}`}><a className ="blue-button blog-button">READ MORE</a></Link>
      </div>
    </div>
    </React.Fragment>

  );
} else {

  return(
    <React.Fragment>
    <Link href = '/blog/[posts]' as = {`/blog/${props.postSlug}`}>
    <div className ="blog-post-wrapper-page">
      <div className ="blog-pic" style={blogImg}></div>
      <div className ="blog-text-container">
        <div className ="blog-title-container">
          <h3>{props.postTitle}</h3>
          <p>{props.postPreview}</p>
        </div>
        <div className ="blog-date-container">
          <p className = 'blog-date'>{props.date}</p>
        </div>
      </div>
    </div>
    </Link>
    </React.Fragment>

  );
 }
}

export default BlogPosts

and the actual page itself

import { useRouter } from 'next/router';
import postsData from '../../data/PostsData.js';
import Navbar from '../../components/Navbar.js';
import '../../style.sass';

function BlogPost(props) {
  const router = useRouter();
  const postData = postsData.find((data) => {return data.slug === router.query.posts});

  const mainImg = {
     backgroundImage: `url("${postData.imgSrc}")`
  };

  return (
    <React.Fragment>
      <Navbar postPage = {true}/>
      <div className = 'main-post-image' style = {mainImg} ></div>
      <h1></h1>
      <p></p>

    </React.Fragment>
  );
}

export default BlogPost

I'm using next 9.0.3

alenart91 commented 5 years ago

So my issue was I had to use the query object along with getInitialProps in the dynamic pages. I was using the router to compare the data and return the proper object for specific posts. When I would navigate from that page the variable I stored it in would return undefined because the query object would be empty. Still not 100% sure why it calls everything again on that page when navigating away from it however.

HaraKeisuke commented 4 years ago

I have same problem.

@alenart91 Did you solve this problem?

kozlovvski commented 4 years ago

Hey, I have the same exact problem. In getInitialProps I check if the query route exists in redux state. When clicking away from the page, the clicked route shows in title, then 404 error shows and then again the page renders.

nwalters512 commented 4 years ago

If someone can provide a small, self-contained example of this failure, I can look into this. I haven't used dynamic routing and I'm not very familiar with it.

Grsmto commented 4 years ago

I solved this by caching whatever you're fetching from the router in a variable. Then I fallback to that variable if the value is null:

let cachedSlug = null

export default () => {
    const router = useRouter()
    const { slug = cachedSlug } = router.query

    cachedSlug = slug

    return (...)
}

Hope this help.