vercel / next.js

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

Unhandled Runtime Error Error: Expected a suspended thenable. This is a bug in React. Please file an issue. #51477

Open dante01yoon opened 1 year ago

dante01yoon commented 1 year ago

Verify canary release

Provide environment information

- node 16.15.0
- package.json

{ // ...
 "dependencies": {
    "@types/node": "20.1.4",
    "@types/react": "18.2.6",
    "@types/react-dom": "18.2.4",
    "autoprefixer": "10.4.14",
    "eslint": "8.40.0",
    "eslint-config-next": "13.4.2",
    "next": "13.4.2",
    "postcss": "8.4.23",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.2",
    "typescript": "5.0.4",
    "tailwindcss-animate": "^1.0.5"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^5.57.1",
    "@typescript-eslint/parser": "^5.59.2",
    "eslint-config-prettier": "^8.8.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-react": "^7.31.11",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.3.4",
    "prettier": "^2.8.7",
    "@tailwindcss/typography": "^0.5.9"
  }
 // ... 
}

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

No response

Link to the code that reproduces this issue or a replay of the bug

--

To Reproduce

app/post/post.tsx

import { use } from "react"
import { getPosts } from "../api/post/getPosts"

export const Post = async () => {
  const posts = use(getPosts())

  return (
    <>
      {posts.map((post) => (
        <div key={post.id} className="bg-white p-4 rounded shadow mb-4">
          <h2 className="text-2xl font-bold mb-2">{post.title}</h2>
          <p className="text-gray-600 mb-2">
            By {post.author} | {post.date}
          </p>
          <p className="mb-4">{post.content}</p>
          <div className="bg-gray-100 p-2 rounded">
            {post.comments.map((comment, idx) => (
              <div key={comment.id} className="mb-2">
                <p className="text-gray-600 mb-1">{comment.author}</p>
                <p>{comment.text}</p>
                <div>{post.time}</div>
              </div>
            ))}
          </div>
        </div>
      ))}
    </>
  )
}

and this is where post component is used.

app/post/page.tsx

import { Suspense } from "react"
import LoadingSkeleton from "../ui/LoadingSkeleton"
import { Post } from "./post"

export default function PostPage() {
  return (
    <div className="container mx-auto py-8">
      <h1 className="text-3xl font-bold mb-6">Posts</h1>
      <div>
        this is not from data fetching: {new Date().getTime().toString()}
      </div>
      <Suspense fallback={<LoadingSkeleton />}>
        {/* @ts-expect-error Async Server Component */}
        <Post />
      </Suspense>
    </div>
  )
}

Describe the Bug

Unhandled Runtime Error
Error: Expected a suspended thenable. This is a bug in React. Please file an issue.

Call Stack
getSuspendedThenable
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (697:10)
getSuspendedThenable
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1777:6)
resolveModelToJSON
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1249:13)
stringify
<anonymous>
stringify
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (181:13)
processModelChunk
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2062:25)
retryTask
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2109:6)
performWork
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1544:13)
listOnTimeout
node:internal/timers (559:17)
processTimers
node:internal/timers (502:7)

Expected Behavior

when remove async keyword in component, error not thrown.

Is it intended?

wonder why this

Which browser are you using? (if relevant)

Chrome 114.0.5735.106 (arm64)

How are you deploying your application? (if relevant)

localhost - yarn dev (development mode)

jnovak-SM2Dev commented 1 year ago

I had a similar issue, removing async from the component fixed it for me.

Vethavear commented 1 year ago

But we need it to be async in order to use await.

DanyloK0 commented 1 year ago

Same error using next-intl in Server component. if the component is not async it works.

lshearer commented 1 year ago

But we need it to be async in order to use await.

@Vethavear If the function is async, you can just await the promise instead of wrapping it with use.

zsombor-guti commented 1 year ago

@lshearer Not sure what you meant by your comment, because there are two options I see, and none of them manage to solve our issue:

  1. Use use(), which is still marked as beta/experimental - wouldn't use it in prod (also, I'm not 100% sure how it works under the hood, and using Promises gives me more control, eg. run multiple requests in parallel with Promise.all)
  2. Mark the server component as async and await the Promise - in which case we get the error the OP posted about.
ehsanbahramidev commented 10 months ago

Same error using next-intl in Server component. if the component is not async it works.

You can solve it by the below link: https://next-intl-docs.vercel.app/docs/environments/server-client-components#async-components

SirawichDev commented 9 months ago

Same error using next-intl in Server component. if the component is not async it works.

useTranslations not working for server component with async you might need to use getTranslations from next-intl/server instead . take a look in this link https://next-intl-docs.vercel.app/docs/environments/server-client-components#async-components

raotaohub commented 8 months ago

please , remove async syntax

Vethavear commented 8 months ago

Thanks for input guys, I guess this is outdated now as we can use getTranslations from next-intl/server

jocarrd commented 5 months ago

Thanks

julianosirtori commented 5 months ago

please , remove async syntax

  • before
export const Post = async () => {
  const posts = use(getPosts())
  ......
}
  • after
export const Post = () => {
  const posts = use(getPosts())
  ......
}

Thanks I had the same problem and this fix worked for me

jorgearuv commented 4 months ago

In my case, the fix was to use const locale = await getLocale() instead.

ulut0002 commented 3 months ago

In my case, I had the getLocale() and getTranslations() working correctly. But I had to modify the root layout.js file:

before: export default async function RootLayout({ children }) {}

after:export default function RootLayout({ children }) {}

GrahamQuan commented 2 months ago
// error
export default async function Page() {
  const t = useTranslations();
 }

 // ok (remove async)
 export default function Page() {
  const t = useTranslations();
 }