Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks not working in the loading page #44249

Open
1 task done
Princezhm opened this issue Dec 22, 2022 · 7 comments
Open
1 task done

Hooks not working in the loading page #44249

Princezhm opened this issue Dec 22, 2022 · 7 comments
Labels
bug Issue was opened via the bug report template.

Comments

@Princezhm
Copy link

Princezhm commented Dec 22, 2022

Verify canary release

  • I verified that the issue exists in the latest Next.js 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

  • do a new installation of next 13
  • add app folder
  • add experimental: { appDir: true }, to the next.config.js file
  • remove pages folder
  • create layout.js page.js and loading.js (the last one is the issue)

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

@Princezhm Princezhm added the bug Issue was opened via the bug report template. label Dec 22, 2022
@Fredkiss3
Copy link
Contributor

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
Copy link
Contributor

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

@logemann
Copy link

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
Copy link

CRIMSON-CORP commented Sep 2, 2023

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
Copy link

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
Copy link

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
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

6 participants