Reputation: 876
I want to reuse a menu I made in react with react-router-dom, but this time in nextjs. The goal is to change the state of the menu to 'false' and the menuName to 'menu' when I click on a link inside the menu.
I use a useEffect function to listen history :
//use effect for page changes
useEffect(() => {
//listen for page changes
history.listen(() => {
setState({ clicked: false, menuName: "Menu" })
})
})
and wrapped my component with withRouter :
import { withRouter } from 'next/router'
[...]
export default withRouter(Header);
Unfortunately, it prints :
TypeError: Cannot read property 'listen' of undefined
Should I better use 'useRouter' to solve this problem? How?
Thank you ;)
Upvotes: 13
Views: 20815
Reputation: 8536
import { useState, useEffect } from "react";
import { Layout, PageLoading } from ".";
import { useRouter } from "next/router";
const LayoutContainer = ({ pageProps, Component, store, setDeviceWidthAction }) => {
const router = useRouter();
const [pageLoading, setPageLoading] = useState(true);
useEffect(() => {
setDeviceWidthAction(window.innerWidth);
setPageLoading(false);
}, []);
useEffect(() => {
const handleStart = (url) => {
setPageLoading(true);
};
const handleStop = () => {
setPageLoading(false);
};
router.events.on("routeChangeStart", handleStart);
router.events.on("routeChangeComplete", handleStop);
router.events.on("routeChangeError", handleStop);
return () => {
router.events.off("routeChangeStart", handleStart);
router.events.off("routeChangeComplete", handleStop);
router.events.off("routeChangeError", handleStop);
};
}, [router]);
if (pageLoading) return <PageLoading />;
return <Layout {...{ pageProps, Component, store, pageLoading }} />;
};
export default LayoutContainer;
Upvotes: 1
Reputation: 876
It worked that way :
import { useRouter } from "next/router";
...
const router = useRouter()
useEffect(() => {
const handleRouteChange = (url) => {
console.log(
`App is changing to ${url}`
)
setState({ clicked: false, menuName: "Menu" })
}
router.events.on('routeChangeStart', handleRouteChange)
// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeStart', handleRouteChange)
}
}, [])
Upvotes: 20