fridays / next-routes

Universal dynamic routes for Next.js
MIT License
2.47k stars 230 forks source link

Any examples with animations? #42

Closed OutThisLife closed 7 years ago

OutThisLife commented 7 years ago

I'd like to be able to prevent loading the route before an animation is done, issue the route change, and then have a loading in animation.

So something like:

onRouteChange = e => {
    e.preventDefault()
    document.body.classList.remove('anim-in')
    document.body.classList.add('anim-out')
    document.body.addEventListener('animationend', () => {
        issueRouteChange()
        document.body.classList.add('anim-in')
    }
}

obviously psuedocode

fridays commented 7 years ago

I didn't try this yet but here is some information that might be helpful: https://github.com/zeit/next.js/issues/88

AmrN commented 7 years ago

Hey @fridays, in order to prevent the top-level component from unmounting on route change, I'm thinking about using a single page pages/index.js which is responsible for choosing which component to render. But I don't know how to use this method with next-routes because I need a way to tell the index.js page which component it should render via the routes definition, maybe something like explicit params.

// routes.js
routes.add('blog', '/blog', 'index', {component: "BlogList"})
routes.add('blog-post', '/blog/:slug', 'index', {component: "BlogPost"})

// pages/index.js
switch (this.props.url.query.component) {
  case 'BlogList':
    // render BlogList
  case 'BlogPost': 
    // render BlogPost
}

So is there anyway I can specify explicit query params like {component: "BlogList"} in the example above, or would you suggest a better way for approaching this problem? Thanks.

fridays commented 7 years ago

Hi @AmrN you can do something like this:

// pages/index.js
import React from 'react'
import routes from '../routes'

const components = {
  blog: props => <div>Blog</div>,
  blogPost: props => <div>Blog Post</div>
}

export default class extends React.Component {
  static async getInitialProps ({asPath}) {
    return routes.match(asPath)
  }

  render () {
    const {route, params, ...props} = this.props

    if (route) {
      const Component = components[route.name]
      Object.assign(props.url.query, params)
      return <Component {...props} />
    }

    return <div>Not found</div>
  }
}

The downsides with this method are no automatic code splitting and you need some custom error handling.