简体   繁体   English

在 Next JS 中更新路由器查询而不触发页面更改事件

[英]Update Router query without firing page change event in Next JS

I want to change a URL query for the current page in Next JS without triggering the page change event.我想在不触发页面更改事件的情况下更改 Next JS 中当前页面的 URL 查询。 My use case is to simply remember the week being viewed in a calendar, similar to Google Calendar .我的用例是简单地记住在日历中查看的星期,类似于 Google Calendar Here's what I've tried:这是我尝试过的:

import Calendar from '../components/Calendar'
import { formatDate } from '../utils'

class CalendarDashboardPage extends React.Component {
  refreshQuery(date) {
    const { pathname, asPath } = this.props.router
    const d = formatDate(date) // YYYY-MM-DD
    this.props.router.push(pathname, asPath, { query: { d }, shallow: true })
  }

  render() {
    return <Calendar onDateChange={this.refreshQuery) />
  }
}

export default withRouter(CalendarDashboardPage)

This almost seems to work OK, but because this.props.router.push triggers a page change in Next, it causes the page loading bar that I'm using ( nprogress ) to appear on screen.这似乎工作正常,但是因为this.props.router.push在 Next 中触发页面更改,它会导致我正在使用的页面加载栏( nprogress )出现在屏幕上。 I've tried this.props.router.push({ query: { d } });我试过this.props.router.push({ query: { d } }); , but no luck. ,但没有运气。

So my question: is there any way to change the router query without triggering events such as routeChangeStart(url) ?所以我的问题是:有没有办法在不 触发诸如routeChangeStart(url)类的事件的情况下更改路由器查询?

You can keep track of the previous pathname and do a conditional check in the routeChangeStart event handler to see if the pathname(without query) changes:您可以跟踪以前的路径名并在routeChangeStart事件处理程序中进行条件检查,以查看路径名(无查询)是否更改:

// _app.js

import Router from "next/router";

let previousPathname = null;

function handleRouteChange(url) {
  const pathname = url.split('?')[0];
  if (previousPathname && previousPathname !== pathname) {
    console.log(`App is changing from ${previousPathname} to ${pathname}...`);
  }
  previousPathname = pathname;
};

Router.events.on("routeChangeStart", handleRouteChange);

...

This may not answer your question directly since it will still trigger Router.events but hopefully can help you with your use case.这可能不会直接回答您的问题,因为它仍会触发Router.events但希望可以帮助您解决用例。

Short version: you can't (at least AFAIK).简短版本:你不能(至少 AFAIK)。

The first requirement to change the URL in the browser without reload the page is to do that in a single page application.在不重新加载页面的情况下在浏览器中更改 URL 的第一个要求是在单页应用程序中执行此操作。

To achieve I'm afraid you need to drop next/router and start to use react-router , in this article you can find details about how to do a SPA with next using react router.要实现这一点,恐怕您需要删除next/router并开始使用react-router ,在本文中,您可以找到有关如何使用 react router 进行 SPA 的详细信息。

Once you have done, with this.props.history.push("/new/url") react router feature you can do what you are looking for.完成后,使用this.props.history.push("/new/url")反应路由器功能,您可以做您正在寻找的事情。

Hope this helps.希望这可以帮助。

My solution was to just use the browser's API.我的解决方案是只使用浏览器的 API。

refreshQuery(date) {
  const dateString = formatDate(date) // YYYY-MM-DD
  window.history.pushState('', '', `?d=${dateString}`)
}

This changes the date URL parameter when the user flips through the calendar, which can be snagged by componentDidMount() when the users refreshes/shares the URL.这会在用户翻阅日历时更改日期 URL 参数,当用户刷新/共享 URL 时,可以通过componentDidMount()捕获该参数。

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

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