next.js icon indicating copy to clipboard operation
next.js copied to clipboard

`app` dir does not work with React.createContext

Open alex-kinokon opened this issue 1 year ago • 9 comments

Verify canary release

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

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #137-Ubuntu SMP Wed Jun 15 13:33:07 UTC 2022
Binaries:
  Node: 16.18.0
  npm: 8.3.0
  Yarn: 1.22.18
  pnpm: 6.32.11
Relevant packages:
  next: 13.0.0
  eslint-config-next: 13.0.0
  react: 18.2.0
  react-dom: 18.2.0

What browser are you using? (if relevant)

N/A, but Node.js is v16.18.0

How are you deploying your application? (if relevant)

next dev

Describe the Bug

Using @emotion/react as jsxImportSource does not work with app dir, with the following error:

Server Error
TypeError: React.createContext is not a function

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack

eval
  (sc_server)/node_modules/@emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js (21:47)
Object.(sc_server)/./node_modules/@emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js
  file:///home/me/app/.next/server/app/page.js (425:1)

console.log(React) at the error site shows that it indeed doesn’t have createContext.

React.version is 18.3.0-next-d925a8d0b-20221024.

Expected Behavior

Using @emotion/react as jsxImportSource works with app dir.

Link to reproduction

https://replit.com/@alex-kinokon/app-playground

To Reproduce

Set jsxImportSource to @emotion/react in tsconfig.json

alex-kinokon avatar Oct 27 '22 02:10 alex-kinokon

Same error, different module. Maybe has something to do with them shipping two different versions of react?

Mine:

TypeError: React__default.default.createContext is not a function

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
eval
webpack-internal:///(sc_server)/./node_modules/react-daisyui/dist/react-daisyui.cjs (5586:60)

BWBama85 avatar Oct 27 '22 03:10 BWBama85

I meet the same error when I use react-query.

in page.tsx:

import { QueryClient } from "@tanstack/react-query";
...
// same error
const queryClient = new QueryClient();

wh5938316 avatar Oct 27 '22 03:10 wh5938316

It seems we need to do this

https://beta.nextjs.org/docs/rendering/server-and-client-components#convention

React context is only for the client side, can someone test it and let me know? I just now reset my git, when it didn’t work, will try in tomorrow

raajnadar avatar Oct 27 '22 03:10 raajnadar

I'll test here in a few.

BWBama85 avatar Oct 27 '22 04:10 BWBama85

This worked. Moved out of layout.tsx and broke out into navbar.tsx for a quick test.

import './globals.css'
import Nav from './navbar'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </head>
      <body>
        <Nav />
        {children}
      </body >
    </html >
  )
}
'use client';

import { Navbar, Dropdown, Button, Menu } from 'react-daisyui'

export default function Nav() {
  return (
    <div className="pb-40 flex w-full component-preview p-4 items-center justify-center gap-2 font-sans">
      <Navbar>
        <Navbar.Start>
          <Dropdown>
            <Button color="ghost" tabIndex={0} className="lg:hidden">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                className="h-5 w-5"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M4 6h16M4 12h8m-8 6h16"
                />
              </svg>
            </Button>
          </Dropdown>
          <a className="btn btn-ghost normal-case text-xl">The Wilson Net</a>
        </Navbar.Start>
        <Navbar.Center className="hidden lg:flex">
          <Menu horizontal className="p-0">
            <Menu.Item>
              <a>Item 1</a>
            </Menu.Item>
            <Menu.Item tabIndex={0}>
              <a>
                Parent
                <svg
                  className="fill-current"
                  xmlns="http://www.w3.org/2000/svg"
                  width={20} height={20}
                  viewBox="0 0 24 24">
                  <path
                    d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"
                  />
                </svg>
              </a>
              <Menu className="p-2 bg-base-100">
                <Menu.Item>
                  <a>Submenu 1</a>
                </Menu.Item>
                <Menu.Item>
                  <a>Submenu 2</a>
                </Menu.Item>
              </Menu>
            </Menu.Item>
            <Menu.Item>
              <a>Item 3</a>
            </Menu.Item>
          </Menu>
        </Navbar.Center>
        <Navbar.End>
          <Button>Get started</Button>
        </Navbar.End>
      </Navbar>
    </div>
  );
}

BWBama85 avatar Oct 27 '22 04:10 BWBama85

@BWBama85 thank you for testing it!!

So now it is clear we cannot use the react hooks on the server so we need to add the use client directive & we need to keep client & server code separate

raajnadar avatar Oct 27 '22 04:10 raajnadar

I think there needs to better error handling saying exactly that^

temrb avatar Oct 27 '22 05:10 temrb

@temrb it is in the beta stage even though the docs are for beta, so we need to accept this pain, the API might also break in the future updates

raajnadar avatar Oct 27 '22 06:10 raajnadar

I have the same issue, but for react-bootstrap. and also tried with MUI. React-Bootstrap does support "Server Side Rendering". https://react-bootstrap.github.io/getting-started/server-side-rendering/

Not sure how in which side should be fixed for, and what it can be done. But it seems very much like you have to wrap every single client component with "use client" for when you want to use server components on it.

ThomasAunvik avatar Oct 27 '22 07:10 ThomasAunvik

Hi, this is expected if the component using createContext isn't marked with use client. We are already working on a better error message and adding it to the docs soon to explain this better, but the behavior here is not a bug, so I am closing this. Thanks for reporting!

balazsorban44 avatar Oct 27 '22 22:10 balazsorban44