Giter Club home page Giter Club logo

Comments (6)

jmikrut avatar jmikrut commented on August 27, 2024 2

Hey @ikenox — is this still happening if you update to the most recent version of Payload beta packages and Next.js canary?

One thing, we're working on compartmentalizing client-side JS from the Payload config which will probably resolve your new useState issue. I bet this is all related.

But we will keep this issue open regardless until we can come up with a custom server example that works with the Local API.

from payload.

SimYunSup avatar SimYunSup commented on August 27, 2024

This seems to be a bug caused by inserting the nextHandler too quickly. nextjs injects AsyncLocalStorage into globalThis when it's ready, and I think it's caused by using the nextHandler before nextjs is ready.

Similar to custom-server example in nextjs, replacing main.ts like below will fix it.

import next from 'next'
import express from 'express'
import { importConfig } from 'payload/node'

import { getPayload } from 'payload'

const expressApp = express()

async function main() {
  const nextApp = next({
    dev: process.env.NODE_ENV !== 'production',
  })
  const nextHandler = nextApp.getRequestHandler()

  const config = await importConfig('../payload.config.ts')
  const payload = await getPayload({ config })
  expressApp.get('/users', (req, res) => {
    payload
      .find({ collection: 'users' })
      .then(({ docs }) => res.json(docs))
      .catch(next)
  })

  nextApp.prepare().then(() => {
    console.log('Next.js started')
    expressApp.use((req, res) => nextHandler(req, res))
    expressApp.listen(3000, () => {
      console.log(globalThis.AsyncLocalStorage)
      console.log('listen on port 3000')
    })
  })
}

void main()

from payload.

ikenox avatar ikenox commented on August 27, 2024

@SimYunSup
Thank you for the advice!

Just moving nextHandler after nextApp.prepare() gave the same error.
ikenox/payload-3.0-demo@a482e0a

By loading payload config after nextApp.prepare(), I managed to show the admin panel.
ikenox/payload-3.0-demo@bd47e01
But I got different errors when visiting admin panel.

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
 ⨯ TypeError: Cannot read properties of null (reading 'useContext')
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at stringify (<anonymous>)
    at stringify (<anonymous>)
 ⨯ TypeError: Cannot read properties of null (reading 'useState')
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at stringify (<anonymous>)

And these errors are disappeared if I remove const payload = await getPayload({ config }) and its related code.
It means that payload v3 with next.js custom server works well, but still cannot use payload local API with it.

from payload.

SimYunSup avatar SimYunSup commented on August 27, 2024

Oh, sorry. I uploaded previous version code. importConfig and getPayload code must be in then block in nextApp.prepare. Because importConfig call loader and loader calls next/navigation. So This will work on your machine too.

import next from 'next'
import express from 'express'
import { importConfig } from 'payload/node'

import { getPayload } from 'payload'

const expressApp = express()

async function main() {
  const nextApp = next({
    dev: process.env.NODE_ENV !== 'production',
  })
  const nextHandler = nextApp.getRequestHandler()

  nextApp.prepare().then(async () => {
    const config = await importConfig('../payload.config.ts')
    const payload = await getPayload({ config })
    expressApp.get('/users', async (req, res) => {
      await payload
        .find({ collection: 'users' })
        .then(({ docs }) => res.json(docs))
        .catch(next)
    })
    console.log('Next.js started')
    expressApp.use((req, res) => nextHandler(req, res))
    expressApp.listen(3000, () => {
      console.log('listen on port 3000')
    })
  })
}

void main()

from payload.

ikenox avatar ikenox commented on August 27, 2024

@SimYunSup
Thanks!

importConfig and getPayload code must be in then block in nextApp.prepare

Yes, actually I can start the server by your code.
ikenox/payload-3.0-demo@ea3bad8

But something still seems not to work well. As I mentioned in this my comment, some errors are occurred instead.
For example, I got the following error when I visit http://localhost:3000/admin/collections/pages :

image

If I stop to use local API, this error is resolved. (ikenox/payload-3.0-demo@8e1da74)

from payload.

ikenox avatar ikenox commented on August 27, 2024

Hi @jmikrut, thanks for looking into this issue!

is this still happening if you update to the most recent version of Payload beta packages and Next.js canary?

Yes, I upgraded payload and next.js but the problem that is mentioned in my this comment still remains.
ikenox/payload-3.0-demo@b02acc3

One thing, we're working on compartmentalizing client-side JS from the Payload config

It sounds great improvement. I too believe it resolves this issue.

from payload.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.