Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Preact signals don't work with Next 13 appDir #45054

Closed
1 task done
XantreDev opened this issue Jan 19, 2023 · 54 comments
Closed
1 task done

Preact signals don't work with Next 13 appDir #45054

XantreDev opened this issue Jan 19, 2023 · 54 comments
Labels
bug Issue was opened via the bug report template.

Comments

@XantreDev
Copy link

Verify canary release

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

Provide environment information

Any enviroment

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

App directory (appDir: true)

Link to the code that reproduces this issue

https://stackblitz.com/edit/nextjs-ayrrca?file=app/layout.js

To Reproduce

Just try to launch and look to the error

Describe the Bug

React signals don't work with next 13 appDir, if there are at least two client side components on the page.
image

 Warning: 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
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
TypeError: Cannot read properties of null (reading 'useMemo')
    at useMemo (C:\Projects\admin-panel\node_modules\.pnpm\next@13.1.1_23e7ztf2chqi3ri6onem3l5mii\node_modules\next\dist\compiled\react\cjs\react.development.js:1781:21)
    at Object.apply (webpack-internal:///(sc_client)/./node_modules/.pnpm/@preact+signals-react@1.2.2_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:17:180)
    at attemptResolveElement (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1218:42) 
    at resolveModelToJSON (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1671:53)    
    at Object.toJSON (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1132:40)
    at stringify (<anonymous>)
    at processModelChunk (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:172:36)      
    at retryTask (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1879:50)
    at performWork (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1917:33)
    at eval (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1308:40)
    at scheduleWork (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:52:25)
    at pingTask (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1307:29)
    at ping (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1320:40)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
Warning: 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
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
TypeError: Cannot read properties of null (reading 'useMemo')
    at useMemo (C:\Projects\admin-panel\node_modules\.pnpm\next@13.1.1_23e7ztf2chqi3ri6onem3l5mii\node_modules\next\dist\compiled\react\cjs\react.development.js:1781:21)
    at Object.apply (webpack-internal:///(sc_client)/./node_modules/.pnpm/@preact+signals-react@1.2.2_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:17:180)
    at attemptResolveElement (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1218:42) 
    at resolveModelToJSON (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1671:53)    
    at Object.toJSON (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1132:40)
    at stringify (<anonymous>)
    at pingTask (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1307:29)
    at ping (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1320:40)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  digest: '900141944'
}
TypeError: Cannot read properties of null (reading 'useMemo')
    at useMemo (C:\Projects\admin-panel\node_modules\.pnpm\next@13.1.1_23e7ztf2chqi3ri6onem3l5mii\node_modules\next\dist\compiled\react\cjs\react.development.js:1781:21)
    at Object.apply (webpack-internal:///(sc_client)/./node_modules/.pnpm/@preact+signals-react@1.2.2_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:17:180)
    at attemptResolveElement (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1218:42) 
    at resolveModelToJSON (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1671:53)    
    at Object.toJSON (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1132:40)
    at stringify (<anonymous>)
    at processModelChunk (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:172:36)      
    at retryTask (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1879:50)
    at performWork (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1917:33)
    at eval (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1308:40)
    at scheduleWork (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:52:25)
    at pingTask (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1307:29)
    at ping (webpack-internal:///(sc_server)/./node_modules/.pnpm/next@13.1.1_23e7ztf2chqi3ri6onem3l5mii/node_modules/next/dist/compiled/react-server-dom-webpack/server.browser.js:1320:40)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  digest: '900141944'

Expected Behavior

Preact signals works as usual

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@XantreDev XantreDev added the bug Issue was opened via the bug report template. label Jan 19, 2023
@XantreDev
Copy link
Author

preactjs/signals#297

@luanmm
Copy link

luanmm commented Feb 4, 2023

Nice to see that this error is not ocurring only with me. I just couldn't identify what is going on in my project.

In my case, this is happening when I use async (in page) function (to fetch data using await).

The message indicates that I'm incorrectly using hooks, or there are more versions of React.

One detail in my project is that I'm using Turborepo, so there are more projects that references React and React DOM (always the same ^18 version for both, so it shouldn't happen because of "multiple versions").

Other thing is that I'm using MUI, that, for now, should be used as "client components". But this seems irrelevant, because I tried to use a simple layout (only html/body tags) and it keeps happening.

Unhandled Runtime Error
Error: Cannot read properties of null (reading 'useMemo')

In console, this is what happens:

web:dev: [ReferenceError: document is not defined]
web:dev: Warning: 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:
web:dev: 1. You might have mismatching versions of React and the renderer (such as React DOM)
web:dev: 2. You might be breaking the Rules of Hooks
web:dev: 3. You might have more than one copy of React in the same app

So, the main problem here is that React is being undefined in runtime, afterall. But I really have no idea how to troubleshoot this.

Thanks in advance for the attention!

@wdcs-kushaltanna
Copy link

wdcs-kushaltanna commented Feb 27, 2023

Facing the same issue. I wish i could use signal with nextjs. Any solution.?

@rexwangcc
Copy link

rexwangcc commented Mar 1, 2023

We are in a similar situation now except that we aren't using Preact signals but simply NextJS 13 with vanilla React, what's weird is that neither yarn build && yarn start nor yarn dev gives the error, but the applications we are hosting on Kubernetes cluster within a container throws... anyone has an idea?

@MikeDigitize
Copy link

We've encountered this issue experimenting with the latest version of Next 13 and signals as we look to transition from Next 12.

We've done a POC with server and client components, figuring out appropriate component hierarchies for various requirements / scenarios, and the most optimal state management approach.

Using context to provide data globally using primitive values worked fine, then switching out to signals (via context) gave us the exact same error in the first post above. We were following the Preact doc guide to using signals for global state.

The page we were experimenting with loaded when we first started the dev server, but as soon as we made any changes to the code (even unrelated to the signal) we got the mis-use of hooks error, and the properties of null useMemo error, and Next got stuck in an infinite recompile loop in the terminal.

Happy to provide code examples if any use, but we've chalked this up to trying to use two very new technologies that we either dont know well enough yet or have early compatibility issues that will be fixed down the line.

@Billcountry
Copy link

Facing the same, looks like I'll need to consider a different state manager

@Cybermage83
Copy link

Confirming that i am experiencing the same thing

@Vichp
Copy link

Vichp commented Mar 13, 2023

Any progress on this ? Thanks

@NitrousBGC
Copy link

Facing the same issue ! Hope it gets fixed.

@danielgroen
Copy link

danielgroen commented Mar 21, 2023

🙋 Same here! Running on:
"next": "13.2.4"
afbeelding
afbeelding
afbeelding

@XantreDev
Copy link
Author

@igotfr
Copy link

igotfr commented Apr 21, 2023

"next": "13.3.0"

'use client'

import { useSignal } from '@preact/signals-react';

export default function Test2(): JSX.Element {
  const count = useSignal(0);

  return <button onClick={() => count.value++}>{count.value}</button>

Error message:

Server Error
Error: 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
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
resolveCurrentlyRenderingComponent
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (7479:11)
Object.useRef
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (7779:33)
eval
node_modules/@preact/signals-react/dist/signals.mjs (1:686)
Object.set [as current]
node_modules/@preact/signals-react/dist/signals.mjs (1:981)
performWork
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (9344:34)
<unknown>
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (9739:12)
scheduleWork
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (78:3)
startWork
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (9738:3)
<unknown>
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (9841:5)
new Promise
<anonymous>
Object.renderToReadableStream
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js (9790:10)
<unknown>
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/server/node-web-streams-helper.js (141:117)
NextTracerImpl.trace
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/server/lib/trace/tracer.js (65:20)
Object.renderToInitialStream
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/server/node-web-streams-helper.js (141:37)
<unknown>
file:///home/notecomm/pnext/tnext2/node_modules/next/dist/server/app-render/app-render.js (923:71)

@med-Haithem
Copy link

i think it's not an issue in Next/React but in Preact Signals

facebook/react#26704 (comment)

@FleetAdmiralJakob
Copy link

Any updates?

@rubenkristian
Copy link

Any updates?

I use preact/signals-react(v^1.3.2) in next (v13.4.4), it work.

@XantreDev
Copy link
Author

preact/signals-react(v^1.3.2) in next (v13.4.4) works but throws error in console
https://stackblitz.com/edit/nextjs-e5kuk5?file=app%2Fpage.js

@fairbairn
Copy link

We have similar issue, using signal and latest of nextjs (13.5.19) and signals-react(1.3.6).

In this case, it's useEffect which is null, but I think any hook (useMemo, useState, useEffect) crashes in this scenario.

@satoshi-cyber
Copy link

I ended up using @preact/signals-core instead of @preact/signals-react, and it works fine with the app directory in Next.js. You can learn more about my approach here: https://twitter.com/bersen0/status/1695908480392077466

@hadnet

This comment has been minimized.

@MrOxMasTer
Copy link

Next.js 14.0.1

image
image

the site can be used, but the signals do not work and cause an error in the consoles.

image
image

@mkurczewski
Copy link

@MrOxMasTer
same for me

@HyperGrapher
Copy link

HyperGrapher commented Nov 1, 2023

the issue for me is very strange. i use it with react-hook-form in client component and whenever i try to give a value to the signal in the onSubmit function, the email input becames unwriteble. the moment i comment out assignment to signal it behaves normal. no error stack or anything.

"@preact/signals-react": "^1.3.6",

@ReangeloJ
Copy link

Encountering the same issue unfortunately

@Amar97

This comment has been minimized.

@HaminJuri
Copy link

same version (latest);
same error;
and nobody is not taking responsibility for the error, not PReact, not Next
Cool : )

@XantreDev
Copy link
Author

When did it start? Which version of next do you use?

@MrOxMasTer
Copy link

When did it start? Which version of next do you use?

next.js 14.0.1

@rfieve
Copy link

rfieve commented Nov 2, 2023

Is it working with next 13.5.6 ?

@XantreGodlike I am currently facing the issue mentioned by @MrOxMasTer in 13.5.6.
Using @preact/signals-react 1.3.6.

@JonAbrams
Copy link

JonAbrams commented Nov 5, 2023

No one seems to have commented about @satoshi-cyber 's fix.

I just tried it out and it works, but with the downside that signals cannot update their TextNode's directly. The components need to re-render on value updates.

Interactive example on StackBlitz

  1. Switch from @preact/signals-react to @preact/signals-core
  2. Create a hook in your project that returns your signal's state:
import { Signal, effect } from '@preact/signals-core';
import { useEffect, useState } from 'react';

export function useSignalState<T>(signal: Signal<T>) {
  const [state, setState] = useState<T>(signal.value);

  useEffect(() => {
    return effect(() => setState(signal.value));
  }, [signal]);

  return state;
}
  1. In your components, read signal values using useSignalState, update values using the original signal:
import { signal } from '@preact/signals-core';
import { useSignalState } from '../hooks/signalState.ts';

const counter = signal(0);

function ClickCounter() {
  const counterState = useSignalState(counter);

  return (
    <div>
      <div>Counter: {counterState}</div>
      <button onClick={() => counter.value++}>Add One</button>
    </div>
  );
}

@MrOxMasTer
Copy link

Dan abramov said the library patch the react internals in unsupported way, don't expect that to work efficiently.

Maybe I don't understand so deeply how react works, but it strikes me that there is something that logically should work like this and it doesn't work in react. Well, it is logical that hooks should update only what changes. This makes the performance higher and there are no useless re-renderers.

@MrOxMasTer
Copy link

No one seems to have commented about @satoshi-cyber 's fix.

It's kind of cool, but what is the rofl then to use signals? Download an extra library. If it was supposed to be a hook replacement, but at the same time we are writing a hook under the hood, which will also cause a billion-dollar re-render of the entire parent component and children.

@MrOxMasTer
Copy link

the advantages of signals are that this is an innovation that was intended as a replacement for hooks. Which is 4 times more productive than them, and does not cause an extra re-render

@med-Haithem
Copy link

Dan abramov said the library patch the react internals in unsupported way, don't expect that to work efficiently.

facebook/react#26704 (comment)

@XantreDev
Copy link
Author

It works efficiently. There is not good way to extend react because it've written unextendable

@JonAbrams
Copy link

JonAbrams commented Nov 5, 2023

I created a library that allows you to use Signals within React (and Next.js) safely: signals-react-safe

It allows rendering of signals directly in JSX, skipping re-renders of the component. If you need to use a signal's value, it provides a new useSignalValue hook that re-renders the component whenever the signal's value changes.

Live demo

@MrOxMasTer
Copy link

MrOxMasTer commented Nov 6, 2023

Я создал библиотеку, которая позволяет вам безопасно использовать сигналы в React (и Next.js): signals-react-safe

I'm asking you again. Why do you need your library if you just used hooks under the hood...

@XantreDev
Copy link
Author

Я создал библиотеку, которая позволяет вам безопасно использовать сигналы в React (и Next.js): signals-react-safe

I'm asking you again. Why do you need your library if you just used hooks under the hood...

I think we should fix signals react integration, because you cannot build an ecosystem with so much amount of runtimes. I see some benefits from using signals with this api, but I don't think it's generally a good idea, because there are not so many benefits against jotai

@MrOxMasTer
Copy link

MrOxMasTer commented Nov 6, 2023

I think we should fix signals react integration, because you cannot build an ecosystem with so much amount of runtimes. I see some benefits from using signals with this api, but I don't think it's generally a good idea, because there are not so many benefits against jotai

I don't understand the meaning of this library at all, when instead of just using useState, you use 3 hooks (useSignal, useState, useEffect), you call even more re-render than it was, killing the signal chip (that they don't have a re-render). Just without any wrapper, the person created hooks that have an efficiency of -100%. And if a global store is needed, the person did not somehow revive the signal function, but simply made hooks. Better zustand/jotai. He would at least read how preact implemented it on custom useSyncExternalStore and did something similar. Just made it worse than hooks. Just adding extra wrappers and an additional library in addition, which does not work.

@MrOxMasTer
Copy link

MrOxMasTer commented Nov 6, 2023

@JonAbrams
Copy link

JonAbrams commented Nov 6, 2023 via email

@MrOxMasTer
Copy link

useSignalValue causes re-renders of the component. Same as if you access a signal’s value directly in a component. If you render the signal directly in the JSX (without .value), it won’t trigger a re-render of the component. Again, that’s how Signals normally works.

I understand that signals should not cause re-rendering. I speak for your library, which is meaningless in my opinion

@XantreDev
Copy link
Author

XantreDev commented Nov 12, 2023

Reproduction

  1. Signals imported into component, but is has not 'use client' directive. If add directive, there is no error, but components is not reactive at all.
    image
    image
    image
    image
  2. We can just import @preact/signals-react in any server side component
    image
    image

Minimal reproduction: https://github.com/XantreGodlike/preact-signals-next-issue

Error log:

 ⚠ Fast Refresh had to perform a full reload due to a runtime error.
 ⨯ node_modules\.pnpm\@preact+signals-react@1.3.6_react@18.2.0\node_modules\@preact\signals-react\dist\signals.mjs (1:2855) @ eval
 ⨯ TypeError: Cannot set property createElement of [object Module] which has only a getter
    at __webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at eval (./src/app/page.tsx:7:79)
    at (rsc)/./src/app/page.tsx (D:\Projects\experiments\preact-signals-next-issue\.next\server\app\page.js:173:1)
    at Function.__webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at async Promise.all (index 0)
null
 ⨯ node_modules\.pnpm\@preact+signals-react@1.3.6_react@18.2.0\node_modules\@preact\signals-react\dist\signals.mjs (1:2855) @ eval
 ⨯ TypeError: Cannot set property createElement of [object Module] which has only a getter
    at __webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at eval (./src/app/page.tsx:7:79)
    at (rsc)/./src/app/page.tsx (D:\Projects\experiments\preact-signals-next-issue\.next\server\app\page.js:173:1)
    at Function.__webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at async Promise.all (index 0)
digest: "51753089"
null
 ⨯ node_modules\.pnpm\@preact+signals-react@1.3.6_react@18.2.0\node_modules\@preact\signals-react\dist\signals.mjs (1:2855) @ eval
 ⨯ TypeError: Cannot set property createElement of [object Module] which has only a getter
    at __webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at eval (./src/app/page.tsx:7:79)
    at (rsc)/./src/app/page.tsx (D:\Projects\experiments\preact-signals-next-issue\.next\server\app\page.js:173:1)
    at Function.__webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
null
TypeError: Cannot set property createElement of [object Module] which has only a getter
    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:204:58)
    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:211:6)
    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:212:2)
    at (rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs (D:\Projects\experiments\preact-signals-next-issue\.next\server\vendor-chunks\@preact+signals-react@1.3.6_react@18.2.0.js:20:1)
    at __webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at eval (webpack-internal:///(rsc)/./src/app/page.tsx:7:79)
    at (rsc)/./src/app/page.tsx (D:\Projects\experiments\preact-signals-next-issue\.next\server\app\page.js:173:1)
    at Function.__webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:538:9)
    at process.processTimers (node:internal/timers:512:7)
    at async eq (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:401020)
    at async tr (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:404747)
    at async tn (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:405297)
    at async tn (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:405428)
    at async tu (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:409639)
    at async D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:410158 {
  digest: '331124788'
}
 ⨯ node_modules\.pnpm\@preact+signals-react@1.3.6_react@18.2.0\node_modules\@preact\signals-react\dist\signals.mjs (1:2855) @ eval
 ⨯ TypeError: Cannot set property createElement of [object Module] which has only a getter
    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:204:58)
    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:211:6)
    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs:212:2)
    at (rsc)/./node_modules/.pnpm/@preact+signals-react@1.3.6_react@18.2.0/node_modules/@preact/signals-react/dist/signals.mjs (D:\Projects\experiments\preact-signals-next-issue\.next\server\vendor-chunks\@preact+signals-react@1.3.6_react@18.2.0.js:20:1)
    at __webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at eval (webpack-internal:///(rsc)/./src/app/page.tsx:7:79)
    at (rsc)/./src/app/page.tsx (D:\Projects\experiments\preact-signals-next-issue\.next\server\app\page.js:173:1)
    at Function.__webpack_require__ (D:\Projects\experiments\preact-signals-next-issue\.next\server\webpack-runtime.js:33:42)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:538:9)
    at process.processTimers (node:internal/timers:512:7)
    at async eq (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:401020)
    at async tr (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:404747)
    at async tn (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:405297)
    at async tn (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:405428)
    at async tu (D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:409639)
    at async D:\Projects\experiments\preact-signals-next-issue\node_modules\.pnpm\next@14.0.2_react-dom@18.2.0_react@18.2.0\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:410158 {
  digest: '331124788',
  page: '/'
}

Hypothesis

seems to be its related with webpack es modules building - it produces immutable object with getters, so preact signals react cannot patch createElement. But react@18.2.0 is still has commonjs imports/exports, probably next doing some stuff with react export on server side

@ronniechoyy
Copy link

ronniechoyy commented Nov 13, 2023

No one seems to have commented about @satoshi-cyber 's fix.

I just tried it out and it works, but with the downside that signals cannot update their TextNode's directly. The components need to re-render on value updates.

Interactive example on StackBlitz

  1. Switch from @preact/signals-react to @preact/signals-core
  2. Create a hook in your project that returns your signal's state:
import { Signal, effect } from '@preact/signals-core';
import { useEffect, useState } from 'react';

export function useSignalState<T>(signal: Signal<T>) {
  const [state, setState] = useState<T>(signal.value);

  useEffect(() => {
    return effect(() => setState(signal.value));
  }, [signal]);

  return state;
}
  1. In your components, read signal values using useSignalState, update values using the original signal:
import { signal } from '@preact/signals-core';
import { useSignalState } from '../hooks/signalState.ts';

const counter = signal(0);

function ClickCounter() {
  const counterState = useSignalState(counter);

  return (
    <div>
      <div>Counter: {counterState}</div>
      <button onClick={() => counter.value++}>Add One</button>
    </div>
  );
}

Thanks man, that's work!
Remain others, only use the "useSignalState" in components , no need in other functions, I'm got confused at start

@akhil-naidu
Copy link

Still need some updates on it, but the signal can be used with the signals/core repository. Also, I would like to have a confirmation on:

If I convert the NextJS react Webpack to Preact Webpack, can I use the signals/react package directly?

@Xam-Mlr
Copy link

Xam-Mlr commented Dec 1, 2023

No one seems to have commented about @satoshi-cyber 's fix.

I just tried it out and it works, but with the downside that signals cannot update their TextNode's directly. The components need to re-render on value updates.

Interactive example on StackBlitz

  1. Switch from @preact/signals-react to @preact/signals-core

  2. Create a hook in your project that returns your signal's state:

import { Signal, effect } from '@preact/signals-core';

import { useEffect, useState } from 'react';



export function useSignalState<T>(signal: Signal<T>) {

  const [state, setState] = useState<T>(signal.value);



  useEffect(() => {

    return effect(() => setState(signal.value));

  }, [signal]);



  return state;

}
  1. In your components, read signal values using useSignalState, update values using the original signal:
import { signal } from '@preact/signals-core';

import { useSignalState } from '../hooks/signalState.ts';



const counter = signal(0);



function ClickCounter() {

  const counterState = useSignalState(counter);



  return (

    <div>

      <div>Counter: {counterState}</div>

      <button onClick={() => counter.value++}>Add One</button>

    </div>

  );

}

In this case what is better than Atom libraries like Jotai ?

@XantreDev
Copy link
Author

XantreDev commented Dec 1, 2023

@Xam-Mlr It's just simplier, btw I've made way to use signals in next.js using hocs.
@preact-signals/safe-react

import { useSignal } from '@preact-signals/safe-react'
import { withTrackSignals } from '@preact-signals/safe-react/manual'

export const Component = withTrackSignals(() => {
  const sig = useSignal(0)
  
  return (
    <div>
      <button onClick={() => sig.value++}>Add one</button>
      Count: {sig.value}
    </div>
  )
})

@XantreDev
Copy link
Author

@LassazVegaz
Copy link

It works efficiently. There is not good way to extend react because it've written unextendable

facts

@XantreDev
Copy link
Author

It works efficiently. There is not good way to extend react because it've written unextendable

facts

It depends on the use case. Only overhead it has - is to track dependecies in each component, it's just adding dependency into the linked list - O(1).
It's effective because it allows to scope rerenders only to child component.
https://preactjs.com/blog/introducing-signals/

@LassazVegaz
Copy link

@XantreGodlike I meant you are right. React is unextensible. And it is written in that way. The actual problem is, that React has lots of legacy code because it is a very old library. They cannot remove and sometimes alter the old code as it will break many existing apps built with old React. Therefore they try not to touch the old code and do the new stuff on the old stuff as a layer. React source code looks freakingly horrible.

PReact on the other hand is written by correcting these mistakes.

@XantreDev
Copy link
Author

@XantreGodlike I meant you are right. React is unextensible. And it is written in that way. The actual problem is, that React has lots of legacy code because it is a very old library. They cannot remove and sometimes alter the old code as it will break many existing apps built with old React. Therefore they try not to touch the old code and do the new stuff on the old stuff as a layer. React source code looks freakingly horrible.

PReact on the other hand is written by correcting these mistakes.

Agree))

@XantreDev
Copy link
Author

I've implemented swc plugin for preact signals tracking in next.js. how to use
Here you can try it out:
https://codesandbox.io/p/github/XantreGodlike/preact-signals-nextjs/main

@samcx
Copy link
Member

samcx commented Jan 4, 2024

@XantreGodlike Thank you for creating that!

I will be moving this to :nextjs: Discussions as this is due to :react:'s implementation instead of a current :nextjs: issue.

If you believe there is a separate issue going on due to :nextjs:, feel free to send us a bug report!

@vercel vercel locked and limited conversation to collaborators Jan 4, 2024
@samcx samcx converted this issue into discussion #60241 Jan 4, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests