[英]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.我在 next.js 中切换导航,它工作正常,只是我希望导航在路线更改时再次关闭。
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.我已经尝试了一些东西 - 我想我想利用 onRouteChangeComplete(url) 但我正在努力更新 navActive 状态。
My page.js file:我的 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>
);
}
}
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.所以应用程序以 false 的 navActive 状态开始,单击 HeaderToggleBar 元素打开和关闭导航。 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.谢谢你。
Have a look at https://github.com/zeit/next.js/#router-events .看看https://github.com/zeit/next.js/#router-events 。 You should be fine with sth like this in the ctor of your Header component:
在 Header 组件的 ctor 中,您应该可以使用这样的东西:
constructor(props){
super(props);
Router.events.on('routeChangeComplete', (url) => {
props.toggle();
});
}
if you're using a functional React component, you can do this:如果您使用的是功能性 React 组件,您可以这样做:
const router = useRouter();
useEffect(() => {
if (isMenuOpen) {
setMenuOpen(!isMenuOpen);
}
}, [router.asPath]);
when route changing is happening, next.js is trying to load the other page.当发生路由更改时,next.js 会尝试加载其他页面。 A better way to handle the route change, if you are tracking the loading state, keep that loading state true, until the route change is complete.
处理路由更改的更好方法是,如果您正在跟踪加载状态,请保持加载状态为真,直到路由更改完成。
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]);
We can use router events to handle this.我们可以使用路由器事件来处理这个。 Refer: https://nextjs.org/docs/api-reference/next/router#usage-6
参考: 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]);
Reference: https://nextjs.org/docs/api-reference/next/router参考:https://nextjs.org/docs/api-reference/next/router
There you can see class component base code.在那里你可以看到类组件的基本代码。 But here I use the functional components to solve this issue.
但是这里我使用功能组件来解决这个问题。
useEffect(() => {
const handleRouteChange = () => {
setOpenDropdown(false)
}
router.events.on('routeChangeStart', handleRouteChange)
}, [])
I believe you need to bind your callback.我相信你需要绑定你的回调。 You might also need to add a constructor.
您可能还需要添加一个构造函数。 Here's an snippet from a project that accepts file uploads.
这是一个接受文件上传的项目的片段。
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>
)
}
}
Use this awesome library which handles routing with redux in nextjs:使用这个很棒的库,它在 nextjs 中使用 redux 处理路由:
https://github.com/danielr18/connected-next-router https://github.com/danielr18/connected-next-router
Complete example<\/strong>完整示例<\/strong>
Using a functional component.使用功能组件。
Triggering on
routeChangeStart<\/code> , so the menu can optionally be animated immediately after clicking.
在
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.