It would be nice if we could pass custom state
to router.push
, same way it's done in browser (using history.pushState
) so we could have same url, but different content.
I would like to use this for a multistep/wizard form, which would be under some url (say /form
) and keep the current step I'm on in history state
. This way I could make it so the back button makes it go back a step.
Currently I couldn't find a solution to make this work, there's no way of providing this custom state & no way to intercept the browser "back" button.
Extra param for router.push
allowing a object to be passed and saved to history state
I've considered handling the back button on my own and deciding wheter the browser should go back or the form should go back, but that's also not possible (a onBack
handler would be required).
This would be useful, I had the same problem but I ended up solving it with hashes. When going a step forward (or backward), transform the current step into a hash and use it with the Router
, something like this:
Router.push({
pathname: '/wizard-form',
hash: convertIndexToHash(stepIndex),
});
Then you end up with URLs like /wizard-form
, /wizard-form#two
, /wizard-form#three
, and so on. I considered the absence of a hash as the first step. To listen to hashes changes, you can do this:
const handleHashChange = () => {
const stepIndex = convertHashToIndex(window.location.hash);
setCurrentStepIndex(stepIndex);
};
useEffect(() => {
Router.events.on('hashChangeComplete', handleHashChange);
return () => {
Router.events.off('hashChangeComplete', handleHashChange);
}
}, []);
@rafaelalmeidatk The downside is that this does not work with server-side rendering, since hashes are not being sent to the server.
@Gersom-NL It is not a downside because it is the same behavior of pushState
, it is client-side only. If you want to make it work with SSR you will have to use query params or change the route (e.g. /wizard-form/one
, /wizard-form/two
).
Be aware that if you don't store the data from the previous steps on your server (you need to submit it after each step), then even if you access /wizard-form/two
and use SSR, you won't have the data of the previous forms (since they are in the memory and are gone with the page refresh). This is why sometimes the client-side solution is preferred.
Data storing is not a problem for us, we already store it in local storage, I just want to keep track of the current step in history so that I can make the back button go back a step.
Also we already render the form only on client, as SSR doesn't make sense and would be too difficult.
I have also been looking for best practices for this issue. In the past, using react router was able to easily push state to history instead of sending a request to the server. This is very important for a similar native application. For example, when a drawer is opened, the user triggers the back behavior on the phone should close the drawer instead of backing to the previous page!
This was recently fixed.
So how we can use this feature to send state on router?
This was recently fixed.
Hi @Timer How to use this feature in Next.js 9.4.2
This was recently fixed.
Hi @Timer can you please tell us how to use this feature?
Any updates on this? It's 2020 we need to pass data between components.
Well, I was also looking how to make this work, I think I kind of got it. I started a brand new project using next 9.5.1. I'm using the browser's history feature in order to send custom data, kinda looks like this:
import React, { useEffect, useState } from 'react';
const TestPage = () => {
const [pageState, setState] = useState(0);
const next = () => {
console.log('Pushing', pageState);
window.history.pushState({
data: pageState + 1
}, undefined, '/test');
setState(pageState + 1);
};
useEffect(() => {
window.addEventListener('popstate', (data) => {
if (data.state?.data) {
setState(data.state.data);
}
});
}, []);
return (<div>
<p>Page state is {pageState}</p>
<button onClick={next}>Navigate next</button>
</div>);
}
export default TestPage;
You should be able to navigate under the same route, using back and forward buttons, and keep track on the state.
If you try to send custom data using pushState
, next will throw an error, in 9.5 this no longer happens. I think that was what @Timer meant.
This was recently fixed.
Hi @Timer How to use this feature in Next.js 9.4.2
This was recently fixed.
@Timer @timneutkens We've 9.5.1, and still nowhere mentioned in docs on how to use this feature ? Please guide us.
How we can use this feature to send state on router?
Most helpful comment
So how we can use this feature to send state on router?