awesome-fastapi-projects icon indicating copy to clipboard operation
awesome-fastapi-projects copied to clipboard

Bug with a hard reload on navigation

Open vladfedoriuk opened this issue 1 year ago • 2 comments

When we use the Next.js router navigation (even just to update the query parameters), the hard reload is happening and the table is flickering (first, the unfiltered table is shown, then the table re-renders and the actual filtered result is displayed).

Perhaps, related to https://github.com/netlify/next-runtime/issues/2089

Also, upgrading Next.js might be helpful: https://github.com/Kludex/awesome-fastapi-projects/issues/26

Overall, it should be investigated how the table flickering on reload can be prevented.

vladfedoriuk avatar Nov 21 '23 20:11 vladfedoriuk

yep, it's related to that, even updating query params messes it up..I had to come up with a hack to work with search params

it only works with search params though, and I didn't implement the scroll flag cause I don't need it

"use client";
import { useSyncExternalStore } from "react";

const isServer = typeof window === "undefined";
class History {
  listeners = new Set<() => void>();

  constructor() {
    if (isServer) {
      return;
    }
    window.addEventListener("popstate", () => {
      this.emit();
    });
  }
  emit() {
    this.listeners.forEach((cb) => cb());
  }
  subscribe = (cb: () => void) => {
    this.listeners.add(cb);
    return () => {
      this.listeners.delete(cb);
    };
  };
  push = (url: string, _: { scroll: boolean }) => {
    if (isServer) {
      return;
    }
    window.history.pushState({}, "", url);
    this.emit();
  };
  replace = (url: string, _: { scroll: boolean }) => {
    if (isServer) {
      return;
    }
    window.history.replaceState({}, "", url);
    this.emit();
  };
  getSnapshot = () => {
    return new URL(window.location.href).searchParams.toString();
  };
}
const customHistory = new History();
export const _useRouter = () => {
  const searchParams = useSyncExternalStore(
    customHistory.subscribe,
    customHistory.getSnapshot,
    () => ""
  );

  return {
    searchParams,
    push: (url: string, options: { scroll: boolean }) => {
      customHistory.push(url, options);
    },
    replace: (url: string, options: { scroll: boolean }) => {
      customHistory.replace(url, options);
    },
  };
};

julia-script avatar Nov 21 '23 23:11 julia-script

@julia-script Thanks for the input! I believe a custom history could be a solution for that. I see there is also some progress on https://github.com/vercel/next.js/discussions/48110, so maybe a fix will be delivered shortly in some future release. I have recently found a package: https://github.com/47ng/next-usequerystate What caught my eye is: https://github.com/47ng/next-usequerystate#shallow

Note: the app router doesn't https://github.com/vercel/next.js/discussions/48110 have this capability natively, but next-usequerystate does, by bypassing the router on shallow updates.

So, I think using this package until a proper fix is introduced in Next.js could be worth trying.

vladfedoriuk avatar Nov 22 '23 20:11 vladfedoriuk