Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing state on route change Next.js

I'm toggling navigation in next.js, it works fine, it's just I want the navigation to close again when the route changes.

For example, if I'm on the home page and toggle the navigation, the navigation opens and shows a link to the about page. If I click that link, I get taken to the about page as expected - but the navigation is still open!

I've tried a few things - I think I want to utilize onRouteChangeComplete(url) but I'm struggling to update the navActive state.

My page.js file:

class Page extends Component {
  state = {
    navActive: false
  };

  toggle = () => {
    this.setState({
      navActive: !this.state.navActive
     });
  };

  render() {
    return (
      <ThemeProvider theme={theme}>
        <StyledPage className="full-page-wrapper">
          <Meta />
          <Header navActive={this.state.navActive} toggle={this.toggle} />
          <PrimaryContent>{this.props.children}</PrimaryContent>
          <GlobalStyle />
        </StyledPage>
      </ThemeProvider>
    );
  }
}

Then my header file:

class Header extends React.Component {
  render() {
    return (
      <HeaderSide

        <HeaderToggleBar onClick={() => this.props.toggle()} />

      </HeaderSide>
    );
  }
}

So the app starts off with navActive state of false, clicking the HeaderToggleBar element opens and closes the nav. But I need to close the nav when the route changes. I guess I could put the click event on the navigation items within the header (so clicking to a new page toggles) but that seems a bit over the top.

Thank you.

like image 950
user3725781 Avatar asked Dec 19 '18 18:12

user3725781


3 Answers

Have a look at https://github.com/zeit/next.js/#router-events. You should be fine with sth like this in the ctor of your Header component:

constructor(props){
  super(props);

  Router.events.on('routeChangeComplete', (url) => {
    props.toggle();
  });
}
like image 119
Rob Avatar answered Oct 28 '22 00:10

Rob


if you're using a functional React component, you can do this:

   const router = useRouter();

   useEffect(() => {
    if (isMenuOpen) {
      setMenuOpen(!isMenuOpen);
    }
  }, [router.asPath]);
like image 37
raptoria7 Avatar answered Oct 28 '22 00:10

raptoria7


We can use router events to handle this. Refer: https://nextjs.org/docs/api-reference/next/router#usage-6

const router = useRouter();
useEffect(() => {
  router.events.on('routeChangeComplete', handleRouteChange)
  return () => {
    router.events.off('routeChangeComplete', handleRouteChange)
  };
}, [router.events]);
like image 12
One Mad Geek Avatar answered Oct 27 '22 23:10

One Mad Geek