Closed czanbaka closed 3 months ago
Automatic tracking for now is not working with next.js. You can use signals with my lib to allow signals tracking for components. I also working on swc transform plugin to allow use signals in next.js https://github.com/XantreGodlike/preact-signals/pull/45
The new 2.0.0 version of @preact/signals-react provides a useSignals()
hook that you can place in any component that reads a signal's value. It appears to work with Nextjs 14+ for me.
I've implemented swc plugin how to use
https://codesandbox.io/p/github/XantreGodlike/preact-signals-nextjs/main
The @preact/signals-react documentation mention two ways:
{
"plugins": [["module:@preact/signals-react-transform"]]
}
useSignals()
- work for me
hook to make your components reactive, but a bit tedious calling it in every component.For next JS you need to use SWC plugin
The @preact/signals-react documentation mention two ways:
- Adding a babel transform - didn't work for me in Next 14.0.1
{ "plugins": [["module:@preact/signals-react-transform"]] }
- call the
useSignals()
- work for me hook to make your components reactive, but a bit tedious calling it in every component.
Why not simply use the useSignal() hook to instantiate a signal
Consider a scenario below
<button onClick={() => count.value++}> Value: {count}, value x 2 = {double} </button>
The above has been referred from the NPM documentation but, small difference is they referred signals as count.value
and double.value
in the JSX. It didn't seem to update the same in UI.
Not until I referred the signals as signal
instead of signal.value
in the JSX.
Consider a scenario below
<button onClick={() => count.value++}> Value: {count}, value x 2 = {double} </button>
The above has been referred from the NPM documentation but, small difference is they referred signals as
count.value
anddouble.value
in the JSX. It didn't seem to update the same in UI.Not until I referred the signals as
signal
instead ofsignal.value
in the JSX.
Reading signal .value
field subscribes a component to it changes only if you are using babel plugin or used useSignals()
on top of a component
So even when I am creating a signal using the useSignal()
hook, still I have to manually call the useSignals()
?
Consider a scenario below
<button onClick={() => count.value++}> Value: {count}, value x 2 = {double} </button>
The above has been referred from the NPM documentation but, small difference is they referred signals ascount.value
anddouble.value
in the JSX. It didn't seem to update the same in UI. Not until I referred the signals assignal
instead ofsignal.value
in the JSX.Reading signal
.value
field subscribes a component to it changes only if you are using babel plugin or useduseSignals()
on top of a component
Also then how using only signal
instead of signal.value
works.
Consider a scenario below
<button onClick={() => count.value++}> Value: {count}, value x 2 = {double} </button>
The above has been referred from the NPM documentation but, small difference is they referred signals ascount.value
anddouble.value
in the JSX. It didn't seem to update the same in UI. Not until I referred the signals assignal
instead ofsignal.value
in the JSX.Reading signal
.value
field subscribes a component to it changes only if you are using babel plugin or useduseSignals()
on top of a component
Also can you explain me the phrase subscribes a component to it
/
So even when I am creating a signal using the
useSignal()
hook, still I have to manually call theuseSignals()
?
Conceptually react integration works like this. Every component wrapped with try finally to start tracking and finish it in finally block.
// start tracking reading of signals
const store = _useSignalsImplementation(1);
try {
return renderYourComponent(props);
} finally {
// stop tracking reading of signals
store.f();
}
If you're using useSignals()
// start tracking and will stop tracking on new microtask
useSignals()
// code
return jsx
You can think about it like every component code wrapped in effect
. If use are not using any react integration - there is no such effect
The @preact/signals-react documentation mention two ways:
- Adding a babel transform - didn't work for me in Next 14.0.1
{ "plugins": [["module:@preact/signals-react-transform"]] }
- call the
useSignals()
- work for me hook to make your components reactive, but a bit tedious calling it in every component.
useSignal doesn't work for me, can't enter anything in the input field
@XantreGodlike Thanks for your plugin, it works well with @preact/signals-react in next.js14.
![]()
It works, finally!
Setup is almost correct. But you should import signal
, computed
, effect
and other functions from @preact-signals/safe-react
not @preact/signals-react
(to avoid undefined behaviour and reduce bundle size)
When I use signal() and return signal.value, it never gets updated on further signal.value updates. The only way to show it and update it is to just return signal, but in that case, if I have a complex object, such as User, I can't just do signal.username, I must do signal.value.username (which would not work as I said above, and as a bonus, if you return signal.value.something on a object, it always shows undefined)
When I use signal() and return signal.value, it never gets updated on further signal.value updates. The only way to show it and update it is to just return signal, but in that case, if I have a complex object, such as User, I can't just do signal.username, I must do signal.value.username (which would not work as I said above, and as a bonus, if you return signal.value.something on a object, it always shows undefined)
Maybe you need valtio.
When I use signal() and return signal.value, it never gets updated on further signal.value updates. The only way to show it and update it is to just return signal, but in that case, if I have a complex object, such as User, I can't just do signal.username, I must do signal.value.username (which would not work as I said above, and as a bonus, if you return signal.value.something on a object, it always shows undefined)
If you need deep reactivity you can use @preact-signals/utils
@OpenSource03 Please provide an example.
That goes for everyone else too, without reproductions, we cannot help.
This thread has gotten pretty off topic so I'm going to close it out as answered.
Just curious if anyone has successfully gotten signals to work with next.js 14? I get this error when I try:
Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'length')
Call Stack areHookInputsEqual node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (10921:0) updateEffectImpl node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (12303:0) updateEffect node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (12323:0) updateSyncExternalStore node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (11802:0) Object.useSyncExternalStore node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (13448:0) useSyncExternalStore node_modules/next/dist/compiled/react/cjs/react.development.js (1797:0) P node_modules/@preact/signals-react/dist/signals.module.js (1:2148) Object.set [as current] node_modules/@preact/signals-react/dist/signals.module.js (1:2976) renderWithHooks node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (10968:0) updateFunctionComponent node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (16163:0) beginWork$1 node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (18359:0) beginWork node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (26741:0) performUnitOfWork node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (25587:0) workLoopConcurrent node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (25573:0) renderRootConcurrent node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (25529:0) performConcurrentWorkOnRoot node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (24382:0) workLoop node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js (261:0) flushWork node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js (230:0) MessagePort.performWorkUntilDeadline node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js (534:0)