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

useMemo problem in Next js when using contentlayer #49267

Closed
1 task done
RajinCoding2007 opened this issue May 5, 2023 · 7 comments
Closed
1 task done

useMemo problem in Next js when using contentlayer #49267

RajinCoding2007 opened this issue May 5, 2023 · 7 comments
Labels
bug Issue was opened via the bug report template.

Comments

@RajinCoding2007
Copy link

RajinCoding2007 commented May 5, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Pro
Binaries:
      Node: 18.13.0
      npm: N/A
      Yarn: N/A
      pnpm: N/A
Relevant packages:
      next: 13.4.0
      eslint-config-next: 13.4.0
      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

https://github.com/RajinCoding2007/Next-ContentLayer-Bug

To Reproduce

I followed contentlayer documentation and used useMDXComponent(post.body.code) to render markdown file and it causes error.

Describe the Bug

I was following contentlayer documentation, I got this error:

- error node_modules\next\dist\compiled\react\cjs\react.shared-subset.development.js (1760:20) @ useMemo
- error TypeError: Cannot read properties of null (reading 'useMemo')
    at Page (./app/posts/[slug]/page.jsx:27:96)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
null
- error node_modules\next\dist\compiled\react\cjs\react.shared-subset.development.js (1760:20) @ useMemo
- error TypeError: Cannot read properties of null (reading 'useMemo')
    at Page (./app/posts/[slug]/page.jsx:27:96)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
digest: "2047166120"
null

Expected Behavior

I expected that MDX page will be rendered successfully. I also made an issue in contentlayer repo:

contentlayerdev/contentlayer#449

Which browser are you using? (if relevant)

Chrome

How are you deploying your application? (if relevant)

No response

@RajinCoding2007 RajinCoding2007 added the bug Issue was opened via the bug report template. label May 5, 2023
@Toshimichi0915
Copy link

Toshimichi0915 commented May 5, 2023

(Deleted as it was misleading)

@wadehammes
Copy link

For me, a similar error happens only when deployed to Vercel, for useEffect:

TanStack/query#5371

@wadehammes
Copy link

I think this is related to #49261

@RajinCoding2007
Copy link
Author

Wrong

export async default function Page({ params }) {

Correct:

export default function Page({ params }) {

I checked the code works fine without async keyword. Please check Page function yourself. Thanks. image

Yes, it works, but what if I really need await inside the Page? I don't need await right now, but I may need this in future.

@Toshimichi0915
Copy link

Toshimichi0915 commented May 5, 2023

useMemo is pointless in server components because it does not re-render at all anyway.

useMDXComponent is defined as follows. So you can simply call getMDXComponent instead of useMDXComponent

export const useMDXComponent = (code: string, globals: Record<string, unknown> = {}) => {
  return React.useMemo(() => getMDXComponent(code, globals), [code, globals])
}
import { allPosts } from 'contentlayer/generated'
import { getMDXComponent } from 'next-contentlayer/hooks'
import { notFound } from 'next/navigation'

export function generateStaticParams() {
  return allPosts.map((post) => ({
    slug: post._raw.flattenedPath,
  }))
}

export default async function Page({ params }) {
  // Find the post for the current page.
  const post = allPosts.find((post) => post._raw.flattenedPath === params.slug)

  // 404 if the post does not exist.
  if (!post) notFound()

  // Parse the MDX file via the getMDXComponent.
  const MDXContent = getMDXComponent(post.body.code)

  return (
    <div>
      {/* Some code ... */}
      <MDXContent />
    </div>
  )
}

@RajinCoding2007
Copy link
Author

useMemo is pointless in server components because it does not re-render at all anyway.

useMDXComponent is defined as follows. So you can simply call getMDXComponent instead of useMDXComponent

export const useMDXComponent = (code: string, globals: Record<string, unknown> = {}) => {
  return React.useMemo(() => getMDXComponent(code, globals), [code, globals])
}
import { allPosts } from 'contentlayer/generated'
import { getMDXComponent } from 'next-contentlayer/hooks'
import { notFound } from 'next/navigation'

export function generateStaticParams() {
  return allPosts.map((post) => ({
    slug: post._raw.flattenedPath,
  }))
}

export default async function Page({ params }) {
  // Find the post for the current page.
  const post = allPosts.find((post) => post._raw.flattenedPath === params.slug)

  // 404 if the post does not exist.
  if (!post) notFound()

  // Parse the MDX file via the getMDXComponent.
  const MDXContent = getMDXComponent(post.body.code)

  return (
    <div>
      {/* Some code ... */}
      <MDXContent />
    </div>
  )
}

Oh, thanks! It works.

@github-actions
Copy link
Contributor

github-actions bot commented Jun 5, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

3 participants