繁体   English   中英

在路由更改时更改状态 Next.js

[英]Changing state on route change Next.js

我在 next.js 中切换导航,它工作正常,只是我希望导航在路线更改时再次关闭。

例如,如果我在主页上并切换导航,导航将打开并显示指向关于页面的链接。 如果我单击该链接,我将按预期进入“关于”页面 - 但导航仍然打开!

我已经尝试了一些东西 - 我想我想利用 onRouteChangeComplete(url) 但我正在努力更新 navActive 状态。

我的 page.js 文件:

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>
    );
  }
}

然后是我的头文件:

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

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

      </HeaderSide>
    );
  }
}

所以应用程序以 false 的 navActive 状态开始,单击 HeaderToggleBar 元素打开和关闭导航。 但是当路线改变时我需要关闭导航。 我想我可以将点击事件放在标题内的导航项上(因此点击新页面切换)但这似乎有点过头了。

谢谢你。

看看https://github.com/zeit/next.js/#router-events 在 Header 组件的 ctor 中,您应该可以使用这样的东西:

constructor(props){
  super(props);

  Router.events.on('routeChangeComplete', (url) => {
    props.toggle();
  });
}

如果您使用的是功能性 React 组件,您可以这样做:

   const router = useRouter();

   useEffect(() => {
    if (isMenuOpen) {
      setMenuOpen(!isMenuOpen);
    }
  }, [router.asPath]);

当发生路由更改时,next.js 会尝试加载其他页面。 处理路由更改的更好方法是,如果您正在跟踪加载状态,请保持加载状态为真,直到路由更改完成。

 const router = useRouter();

 useEffect(() => {
    const handleComplete = () => {
      setIsLoading(false);
    };
    router.events.on("routeChangeComplete", handleComplete);
    router.events.on("routeChangeError", handleComplete);

    return () => {
      router.events.off("routeChangeComplete", handleComplete);
      router.events.off("routeChangeError", handleComplete);
    };
  }, [router]);

我们可以使用路由器事件来处理这个。 参考: 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]);

参考:https://nextjs.org/docs/api-reference/next/router

在那里你可以看到类组件的基本代码。 但是这里我使用功能组件来解决这个问题。

useEffect(() => {
    const handleRouteChange = () => {
        setOpenDropdown(false)
    }
    router.events.on('routeChangeStart', handleRouteChange)
}, [])

我相信你需要绑定你的回调。 您可能还需要添加一个构造函数。 这是一个接受文件上传的项目的片段。

    class Files extends React.Component {
        // define your constructor and call super before setting state vars
        constructor(props){
            super(props);
            this.state = {
                uploadStatus: false
            }
            // Bind your callback
            this.handleUploadImage = this.handleUploadImage.bind(this);
            // set other initial vars if needed
        }

        handleUploadImage(files){
            // do stuff with the files
        }

        render () {
            return (
                <div id="fileContainer">
                    <MyDropzone id={this.props.project._id} onDrop={this.handleUploadImage}>
                        {({getRootProps}) => <div {...getRootProps()} />}
                    </MyDropzone>
                </div>
            )
        }
    }

使用这个很棒的库,它在 nextjs 中使用 redux 处理路由:

https://github.com/danielr18/connected-next-router

完整示例<\/strong>

使用功能组件。

routeChangeStart<\/code>上触发,因此可以选择在单击后立即为菜单设置动画。

import { useRouter } from 'next/router';

const Menu = () => {
  const router = useRouter();
  const [show, setShow] = useState(false);

  const hide = useCallback(() => {
    setShow(false);
  }, [setShow]);

  useEffect(() => {
    // subscribe
    router.events.on('routeChangeStart', hide);
    
    // unsubscribe
    return () => router.events.off('routeChangeStart', hide);
  }, [hide, router.events]);

  return show ? <div>menu</div> : null
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM