reactjs 在路由更改Next.js上更改状态

gdrx4gfi  于 2022-12-18  发布在  React
关注(0)|答案(7)|浏览(188)

我在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元素可以打开和关闭导航。但当路线改变时,我需要关闭导航。我想我可以将单击事件放在标题中的导航项上(这样单击到新页面就会切换),但这似乎有点过了头。
谢谢你。

vc9ivgsu

vc9ivgsu1#

如果您使用的是功能性React组件,则可以执行以下操作:

const router = useRouter();

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

ui7jx7zq2#

看看https://github.com/zeit/next.js/#router-events,在Header组件的ctor中应该可以看到类似这样的内容:

constructor(props){
  super(props);

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

yhuiod9q3#

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

woobm2wo4#

完整示例

使用功能组件。
routeChangeStart上触发,因此可以选择在单击后立即设置菜单动画。

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
}

管理嵌套(类型脚本)

我需要这样的东西在顶层,虽然我会分享:
x一个一个一个一个x一个一个二个x

qc6wkl3g

qc6wkl3g5#

当路由改变发生时,next.js试图加载另一个页面。2处理路由改变的一个更好的方法是,如果你正在跟踪加载状态,保持加载状态为真,直到路由改变完成。

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]);
c2e8gylq

c2e8gylq6#

Reference: https://nextjs.org/docs/api-reference/next/router
在那里你可以看到类组件的基本代码。但是在这里我使用函数组件来解决这个问题。

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

agyaoht77#

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

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

相关问题