I am trying to get an useEffect to execute some code when a user changes the page via the navigation.
My problem is that the useEffect does not execute on the route change (does not show up in console). It does only show up on the first initial page load and never after
I used the google analytics example from nextJS
This is my simple _app.tsx
import type { AppProps } from "next/app";
import "./styles/css.scss";
import { useRouter } from "next/dist/client/router";
import { useEffect} from "react";
const Child: React.FC = ({ children }) => {
return (
<>
<div>{children}</div>
</>
);
};
const App = ({ Component, pageProps }: AppProps) => {
const router = useRouter();
useEffect(() => {
console.log("called");
}, [router.events]);
return (
<>
<Child>
<Component {...pageProps} />
</Child>
</>
);
};
export default App;
Adding the useEffect() (or Effect Hook) hook in Next. js is not at bad as one would think. Let's take a look at an example. We will use useEffect to add an event listener to handle when a user scrolls.
There is no way to pass data between pages with Next's router. You would have to either use query strings as you mentioned, sessionStorage, or a state management option like Redux or React's Context API. You could then put that in your pages/_app.
Let's now declare a withReactRouter HOC to wrap the application with the proper router: // next/with-react-router. js import React from 'react'; import {BrowserRouter} from 'react-router-dom'; const isServer = typeof window === 'undefined'; export default App => { return class AppWithReactRouter extends React.
I was able to get this working more simply, by listening for changes to router.asPath
.
useEffect(() => {
console.log('useEffect fired!', {asPath: router.asPath});
}, [router.asPath]);
You can use routeChangeStart
, routeChangeComplete
and routeChangeError
events to do some functionality whenever the route is changing.
Here I use NProgress to show slim progress bar, if you want you can try the same thing and get some idea about how its working or you can just log some data, () => { console.log("route change start") }
import '../styles/globals.css'
import 'nprogress/nprogress.css'
import NProgress from 'nprogress'
import { Router } from 'next/dist/client/router'
Router.events.on('routeChangeStart', () => {
NProgress.start()
})
Router.events.on('routeChangeComplete', () => {
NProgress.done()
})
Router.events.on('routeChangeError', () => {
NProgress.done()
})
function MyApp({ Component, pageProps }) {
return (
<div>
<h1 style={{ textAlign: 'center', alignItems: 'center' }}>
Welcome to my App
</h1>
<Component {...pageProps} />
</div>
)
}
export default MyApp
Thank to @Faruk answer, I was able to find that it was possible but I had to use those router.events.on inside my hook.
useEffect(() => {
router.events.on("routeChangeComplete", () => {
console.log("route change routeChangeComplete");
});
return () => {
router.events.off("routeChangeComplete", () => {
console.log("stoped");
});
};
}, [router.events]);
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