Open orinokai opened 9 months ago
Hi. I read the source code of Next.js and find quick fix.
Firstly explain the reason why this happens.
In Next.js, server components including not-found.jsx
are always being processed by the React server component's function "renderToReadableStream".
In this function, all the bundled server components including not-found.jsx
( not-found-jsx
are bundled in build phase whether or not the user is seeing not-found page or not! ) are processed by Renderer of React Server and create JSON like formatted data later send to browser. In this process, Renderer of React Server must understand what to render for serverside and getData is called in server-side.
I am seeking how to fix this for the source code of Next.js now, However there is a quick fix.
Since not-found.jsx
is server-component, it is render at server. So you can just use client component to bypass this problem.
Here is the code. I hope it help you.
app/not-found.jsx
import NotFoundImpl from "@/src/not-found-impl";
export default async function NotFound() {
return (
<NotFoundImpl/>
)
}
src/non-found-impl.jsx
'use client'
import React, {useEffect, useState} from "react";
export default function NotFoundImpl() {
const [count, setCount] = useState(0);
useEffect(() => {
fetch(`https://kounter.vercel.app/hit/h3ZJ97ra9Q`, { cache: "no-store" })
.then((result) => result.json())
.then((result) => {
setCount(result.count);
})
}, [])
return (
<>
<h1>Hit</h1>
<p>The API has been hit {count} times</p>
</>
)
}
or maybe you have to add
module.exports = {
reactStrictMode: false,
}
in next.config.js to prevent useEffect from being called twice.
I will keep seeking other fix in source codes. Thank you!
thanks @coffeecupjapan - that would fix the problem in this case, but there are other cases where it is important to be able to fetch on the server. i appreciate the suggestion though
@orinokai
Hi. I try to fix this issue in source code. And codes below delete not-found.js
from bundle and fix issue above.
https://github.com/coffeecupjapan/next.js/commit/497e87fe8f3633dded45c8928b922b6f53a7625e
However, it could not pass test cases that throw notFound()
in server or throw notFound()
in client navigation. I could not find way to revive deleted not-found.js
in bundle in first case, and for second case I have totally no idea.
I hope any maintainer would tackle this issue.
Hi. I read the source code of Next.js and find quick fix.
Firstly explain the reason why this happens. In Next.js, server components including
not-found.jsx
are always being processed by the React server component's function "renderToReadableStream".In this function, all the bundled server components including
not-found.jsx
(not-found-jsx
are bundled in build phase whether or not the user is seeing not-found page or not! ) are processed by Renderer of React Server and create JSON like formatted data later send to browser. In this process, Renderer of React Server must understand what to render for serverside and getData is called in server-side.I am seeking how to fix this for the source code of Next.js now, However there is a quick fix.
Since
not-found.jsx
is server-component, it is render at server. So you can just use client component to bypass this problem. Here is the code. I hope it help you.app/not-found.jsx
import NotFoundImpl from "@/src/not-found-impl"; export default async function NotFound() { return ( <NotFoundImpl/> ) }
src/non-found-impl.jsx
'use client' import React, {useEffect, useState} from "react"; export default function NotFoundImpl() { const [count, setCount] = useState(0); useEffect(() => { fetch(`https://kounter.vercel.app/hit/h3ZJ97ra9Q`, { cache: "no-store" }) .then((result) => result.json()) .then((result) => { setCount(result.count); }) }, []) return ( <> <h1>Hit</h1> <p>The API has been hit {count} times</p> </> ) }
or maybe you have to add
module.exports = { reactStrictMode: false, }
in next.config.js to prevent useEffect from being called twice.
I will keep seeking other fix in source codes. Thank you!
im experiencing this issue even after making it a client component
Link to the code that reproduces this issue
https://github.com/orinokai/test-next-404-fetch
To Reproduce
next start
or deployed to Vercel)Current vs. Expected behavior
The counter is incremented via a
fetch
request in the Not Found page. The fetch request should only be made when the Not Found page is rendered, but is currently seen to happen multiple times during build and at runtime when requesting any page on the site (even statically rendered pages).Provide environment information
Which area(s) are affected? (Select all that apply)
App Router
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local), next start (local), Vercel (Deployed), Other (Deployed)
Additional context
This bug seems to occur with or without the
{ cache: "no-store" }
on the fetch call in the Not Found page