Reputation: 328
we are using Nextjs in our web app. We want to keep stack of pages where users visit to keep state of component on back navigation. How should we do that? I have tried https://github.com/exogen/next-modal-pages, but it calls getInitialProps of previous pages again on back.
Upvotes: 3
Views: 9217
Reputation: 1404
Here's my solution with a custom _app.js
import React, { useRef, useEffect, memo } from 'react'
import { useRouter } from 'next/router'
const ROUTES_TO_RETAIN = ['/dashboard', '/top', '/recent', 'my-posts']
const App = ({ Component, pageProps }) => {
const router = useRouter()
const retainedComponents = useRef({})
const isRetainableRoute = ROUTES_TO_RETAIN.includes(router.asPath)
// Add Component to retainedComponents if we haven't got it already
if (isRetainableRoute && !retainedComponents.current[router.asPath]) {
const MemoComponent = memo(Component)
retainedComponents.current[router.asPath] = {
component: <MemoComponent {...pageProps} />,
scrollPos: 0
}
}
// Save the scroll position of current page before leaving
const handleRouteChangeStart = url => {
if (isRetainableRoute) {
retainedComponents.current[router.asPath].scrollPos = window.scrollY
}
}
// Save scroll position - requires an up-to-date router.asPath
useEffect(() => {
router.events.on('routeChangeStart', handleRouteChangeStart)
return () => {
router.events.off('routeChangeStart', handleRouteChangeStart)
}
}, [router.asPath])
// Scroll to the saved position when we load a retained component
useEffect(() => {
if (isRetainableRoute) {
window.scrollTo(0, retainedComponents.current[router.asPath].scrollPos)
}
}, [Component, pageProps])
return (
<div>
<div style={{ display: isRetainableRoute ? 'block' : 'none' }}>
{Object.entries(retainedComponents.current).map(([path, c]) => (
<div
key={path}
style={{ display: router.asPath === path ? 'block' : 'none' }}
>
{c.component}
</div>
))}
</div>
{!isRetainableRoute && <Component {...pageProps} />}
</div>
)
}
export default App
Gist - https://gist.github.com/GusRuss89/df05ea25310043fc38a5e2ba3cb0c016
Upvotes: 7
Reputation: 35553
You can't "save the state of the page by not un-mounting it" but you can save the state of your app in _app.js
file, and the rebuild the previous page from it.
Check the redux example from next
's repo.
Upvotes: 0