I want to get values of history and match in this.props. I am using next/router
to import withRouter
. I wanted to use this.props.match.params to get values in the url and history.push
to redirect. How can get this in Next.js. Right now I am not getting history and match in this.props.
EDIT: I had to turn back to the global Router. The useRouter hook does not work, since its life cycle seems to be different and thus I cannot grab the exact values that I need at the given times.
.....
if (
!shallow &&
!(EXCEPTIONS.includes(nextUrl) || EXCEPTIONS.includes(Router.asPath)) &&
nextUrl !== Router.asPath
) {
setPreviousRoute(Router.asPath);
}
};
useEffect(() => {
Router.events.on('beforeHistoryChange', handleBeforeHistoryChange);
return () => {
Router.events.off('beforeHistoryChange', handleBeforeHistoryChange);
};
}, []);
return { previousRoute };
};
EDIT: Since the global Router object pollution is not a nice thing to do, you could use a state variable instead:
const EXCEPTIONS = ['/sign-up'];
/**
* Saves the current URL before changing the route.
*/
const useRouteUrlHistory = () => {
const [previousRoute, setPreviousRouter] = useState('');
const router = useRouter();
const handleBeforeHistoryChange = (url) => {
const [nextUrl] = url?.split('?') || [];
if (
!(EXCEPTIONS.includes(nextUrl) || EXCEPTIONS.includes(router.asPath)) &&
nextUrl !== router.asPath
) {
setPreviousRouter(router.asPath);
}
};
useEffect(() => {
router.events.on('beforeHistoryChange', handleBeforeHistoryChange);
return () => {
router.events.off('beforeHistoryChange', handleBeforeHistoryChange);
};
}, []);
return { previousRoute };
};
export default useRouteUrlHistory;
You have to use the hook in your _app.js since you listen for route changes and want to save/access the previousRoute globally.
const MyApp = ({ Component, pageProps }) => {
const { previousRoute } = useRouteUrlHistory();
return (
<ApplicationContext.Provider
value={{
previousRoute,
... another global context
}}
>
... components etc.
</ApplicationContext.Provider>
=====
I have not found an elegant way to be able to access Router.history in its entirety. But often enough I wanted to access at least the last visited route, which forced me to this workaround. It might not be the most elegant way since it pollutes the global Router object, but as I said I have not found any alternative.
I only check for the actual route which was visited previously. You may also implement your logic to check the params. The hook plugs-in before the Router handles the actual Route change. Which allows you to listen to the Router.previousRoute property within you application.
KEEP IN MIND if you do shallow Routing you may not affect the Router.history, which will probably not trigger this event hook.
const EXCEPTIONS = ['/sign-up'];
/**
* Saves the current URL before changing the route.
* The previousRoute is then accessible via the global Router.
*/
const useRouteUrlHistory = () => {
const handleBeforeHistoryChange = (url) => {
const [nextUrl] = url?.split('?') || [];
if (
!(EXCEPTIONS.includes(nextUrl) || EXCEPTIONS.includes(Router.asPath)) &&
nextUrl !== Router.asPath
) {
Router.previousRoute = Router.asPath;
}
};
useEffect(() => {
Router.events.on('beforeHistoryChange', handleBeforeHistoryChange);
return () => {
Router.events.off('beforeHistoryChange', handleBeforeHistoryChange);
};
}, []);
};
export default useRouteUrlHistory;
next/router
doesn't provide you history as react-dom-router
does, it gives you something called query in your component's props
.
This is the official usage example.
import { useRouter } from 'next/router'
const Post = () => {
const router = useRouter()
const { pid } = router.query
return <p>Post: {pid}</p>
}
export default Post
If you want to push routes, you can follow this one. example.
import Router from 'next/router'
function ReadMore() {
return (
<div>
Click <span onClick={() => Router.push('/about')}>here</span> to read more
</div>
)
}
export default ReadMore
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With