pmndrs / react-three-next

React Three Fiber, Threejs, Nextjs starter
https://react-three-next.vercel.app/
MIT License
2.52k stars 342 forks source link

Consider using Next.js page properties #76

Closed jere-co closed 2 years ago

jere-co commented 2 years ago

First of all thanks for the great starter. Truly streamlined to get things running with Next.js despite my limited understanding of Three.js.

Having said that, I find the approach inside _app.js to be rather unusual for a Next.js application, as this all could be achieved with Next.js page properties - or is there something I'm missing here?

The following works great and, unlike the current approach, works out of the box with normal Next.js pages:

/src/pages/index.tsx

import dynamic from 'next/dynamic'

import Instructions from '@/components/dom/Instructions'

const Shader = dynamic(() => import('@/components/canvas/Shader/Shader'), {
  ssr: false,
})

const Page = () => {
  return <Instructions />
}

Page.r3f = <Shader />

export default Page

export async function getStaticProps() {
  return {
    props: {
      title: 'Index',
    },
  }
}

/src/pages/_app.tsx

import { useRouter } from 'next/router'
import useStore from '@/helpers/store'
import { useEffect } from 'react'
import Header from '@/config'
import Dom from '@/components/layout/dom'
import '@/styles/index.css'
import dynamic from 'next/dynamic'

const LCanvas = dynamic(() => import('@/components/layout/canvas'), {
  ssr: false,
})

import type { AppProps } from 'next/app'
import type { NextPage } from 'next'

type NextPageWithR3F = NextPage & {
  r3f?: React.ReactNode
  title: string
}

type AppPropsWithR3F = AppProps & {
  Component: NextPageWithR3F
}

function App({ Component, pageProps }: AppPropsWithR3F) {
  const router = useRouter()

  useEffect(() => {
    useStore.setState({ router })
  }, [router])

  return (
    <>
      <Header title={pageProps.title} />
      <Dom>
        <Component {...pageProps} />
      </Dom>
      <LCanvas>{Component?.r3f}</LCanvas>
    </>
  )
}

export default App
PhiDung-hub commented 2 years ago

This is a good solution, agree

RenaudRohlinger commented 2 years ago

@jere-co Awesome! Didn't know about this and I love this approach. I will update the starter 👍