更改路由更改 Next.js 的状态

Posted

技术标签:

【中文标题】更改路由更改 Next.js 的状态【英文标题】:Changing state on route change Next.js 【发布时间】:2019-05-20 06:57:09 【问题描述】:

您好,我正在 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>
    );
  

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

谢谢。

【问题讨论】:

所以我通过将 onClick 事件应用于导航中的所有链接来“工作” - 所以它关闭导航然后导航到页面。这似乎不切实际,也不是很有未来的证据。此外,如果在导航打开时单击页面上的其他链接,它将保持打开状态。如果路线发生变化,我只需要一个导航关闭的解决方案? 【参考方案1】:

看看https://github.com/zeit/next.js/#router-events。您应该在 Header 组件的 ctor 中处理这样的事情:

constructor(props)
  super(props);

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

【讨论】:

嗨,Rob,谢谢。它不起作用,因为我收到错误:未定义道具。我已将路由器事件放在 Header.js 文件中,但没有放在构造函数中,因为它会导致似乎是无限循环并使浏览器崩溃。 我添加了 ctor 的完整代码...应该可以工作了。【参考方案2】:

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

   const router = useRouter();

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

【讨论】:

秘密仅在skipping参数, [router.asPath]上。【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于更改路由更改 Next.js 的状态的主要内容,如果未能解决你的问题,请参考以下文章

如何不在 Next.js 动态路由之间保持状态?

Next.js:如何在特定页面上更改根 div __next 的 css?

Next.Js : 更改页面而不停止音频

Next JS 静态站点:将特定路由重定向到另一个站点?

当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件

在 next.js 应用程序上管理用户的全局状态