vercel / next.js

The React Framework
https://nextjs.org
MIT License
123.03k stars 26.28k forks source link

Hooks not working in the `loading` page #44249

Open Princezhm opened 1 year ago

Princezhm commented 1 year ago

Verify canary release

Provide environment information

brand new clean install of Next13

Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 22.1.0: Sun Oct  9 20:14:54 PDT 2022; root:xnu-8792.41.9~2/RELEASE_X86_64
    Binaries:
      Node: 16.15.0
      npm: 8.5.5
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.0.8-canary.3
      eslint-config-next: 13.0.7
      react: 18.2.0
      react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue

local

To Reproduce

Layout Code:

export default function Layout({ children }) {
  return (
    <html>
      <head>
        <title>Next.js</title>
      </head>
      <body>{children}</body>
    </html>
  );
}

page code:

// this function is just a hacky way to keep the loading screen visible for 60 seconds.
const awaitLoader = async () => new Promise((r) => setTimeout(r, 60000));

export default async function Page() {
  await awaitLoader();
  return <h1>Hello, Next.js!</h1>;
}

loading code:

"use client"; //<----- using the client component version

import { useEffect, useState } from "react";

export default function Loading() {
  // notice we use this `message` just to see if the UI is being updated
  const { message, setMessage } = useState("genesis of the component");

  useEffect(() => {
   // this console.log is never called
    console.log("calling use effect!");
   // update the message to see if anything gets reflected.
    setMessage("we may think it is loading");
  }, []);

  // loggin outside of everything.... no log either (example of where I do my call)
  console.log(message);

  // this in the HTML is reflected as <div> TESTIN LOADER: </div>
  return <div> TESTING LOADER: {message}</div>;
}

Screenshot 2022-12-22 at 00 49 09 Screenshot 2022-12-22 at 00 49 22

Describe the Bug

I found this bug while creating a loading screen for my application, I was trying to use anime.js in the loading screen and then I noticed none of the hooks I defined where being called.

despite that I was able to call my function animateEverything outside of everything, as I stated on the steps and it started to work (actually the animation was starting) but when I was trying to build I got an error like this:

ReferenceError: NodeList is not defined
--
23:57:47.063 | at toArray (/vercel/path0/.next/server/chunks/881.js:500:20)
23:57:47.063 | at parseTargets (/vercel/path0/.next/server/chunks/881.js:823:87)
23:57:47.063 | at getAnimatables (/vercel/path0/.next/server/chunks/881.js:828:16)
23:57:47.063 | at createNewInstance (/vercel/path0/.next/server/chunks/881.js:1024:21)
23:57:47.063 | at anime (/vercel/path0/.next/server/chunks/881.js:1112:18)
23:57:47.063 | at triggerAnime (/vercel/path0/.next/server/app/page.js:1310:55)
23:57:47.063 | at Loader (/vercel/path0/.next/server/app/page.js:1327:5)

also another thing that I noticed was that if I put some functions with more logs in the code, they were appearing on the terminal instead of the chrome console. for example

loading code:

"use client";

import { useEffect } from "react";

export default function Loading() {
  const doSomething = () => {
    console.log("I'm doing something"); // appears on the terminal
  };

  useEffect(() => {
    // this console.log is never called
    console.log("calling use effect!");

    doSomething();
  }, []);

  console.log(message); // it doesn't appear anywhere
  doSomething();

  return <div> TESTING LOADER: {message}</div>;
}

other things that I was testing is leaving the loading.js file as a server component and create another with the loader, then call it from loading.js but same behaviour.

Expected Behavior

it should behave as a client component and use correctly the hooks without problems.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

Vercel

Fredkiss3 commented 1 year ago

I think the loading behavior is a hard problem to solve Since nextjs uses streaming to show loading before the page has finished loading even JavaScript code. Because of that your loading page cannot be interactive because nextjs has to load the JS first, hydrate your page then run the client code.

It cannot work when your user load the page first (full reload of the browser), but i think it could work between page transitions, since the JS has already been loaded. But i could also be wrong about page transitions and the loading page cannot be interactive 🤷🏾‍♂️.

Fredkiss3 commented 1 year ago

@reza-ebrahimi are you sure you are on the right issue ?

logemann commented 1 year ago

Based on my understanding this is related to React v18.0 new StrictMode modes.

dont know either how this is related but thanks for sharing the side effect of strict mode... i wondered why i have all these double calls in my code ;-)

CRIMSON-CORP commented 10 months ago

Any progress on this? i am having the same issue, i cannot run hooks in loading js, it works when i navigate to tother pages, but not when i first load the page

CRIMSON-CORP commented 10 months ago

I think it makes sense for hooks not to work, as the JavaScript needed to run the hook is still "loading", that's why the loading page exists

scally-betterup commented 3 months ago

The docs indicate that this should work

https://nextjs.org/docs/app/api-reference/file-conventions/loading

By default, this file is a Server Component - but can also be used as a Client Component through the "use client" directive.

But I am also having this problem -- when loading.js sets use client, its hooks and its child component hooks aren't called

mfb-remotesocial commented 2 weeks ago

Likewise, I'm trying to create an animated loading spinner using react-spring, and failing on the loading.tsx page as no useEffect seems to be called. The root svg element is loaded, however, no updates occur to the documents state.