You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Preact, a fast and lightweight drop-in replacement for React, has a pluggable renderer that allows them to add new state and rendering primitives without a wholesale re-write. Signals are one of the new primitives they created. In this introductory article they lay out some advantages of signals over hooks.
Proposed Actions
While signals are an interesting pattern to explore, the more useful action here would be to implement signals for the purpose of developing a similarly pluggable layout rendering pipeline. This would ensure that, as better reactive patterns are developed, IDOM can more easily evolve with them.
The signal pattern seems preferable to contexts in most cases. Contexts have the benefit of being scoped to a given ContextProvider which means that one context can have different values under different providers. To achieve the same thing with signals you'd just have to declare more of them. With that said, allowing the same context to have two different values seems like a confusing concept to wrap your head around, so maybe signals are better in this respect too.
Anyway, something to consider when it comes time to document contexts - perhaps we'd want to push the signal pattern instead.
I'm realizing that signals could actually be better than the standard use_state hook if integrated a bit more into ReactPy's core layout rendering logic. Instead of re-rending a whole component, if you pass a signal directly as a prop or child of an element, ReactPy could intelligently update the value for you without requiring the whole component to re-render.
For example, this would cause an infinite loop:
fromtimeimportsleepfromthreadingimportThread@componentdefInfiniteLoop():
count, set_count=use_state(0)
Thread(target=lambda: sleep(1) orset_state(state+1)).run()
returnhtml.p("Current value is:", count)
However, with signals...
fromtimeimportsleepfromthreadingimportThread@componentdefRendersOnce():
count=use_signal(0)
Thread(target=lambda: sleep(1) orsignal.value :=signal.value+1).run()
returnhtml.p("Current value is:", count)
The component RendersOnce would, as the name suggests, only render once. Nonetheless the <p> element would receive a single update after the expected delay.
Activity
rmorshea commentedon Jan 7, 2023
On thinking about this a bit. I actually think the current design is flexible enough to accommodate signals:
rmorshea commentedon Jan 7, 2023
The signal pattern seems preferable to contexts in most cases. Contexts have the benefit of being scoped to a given
ContextProviderwhich means that one context can have different values under different providers. To achieve the same thing with signals you'd just have to declare more of them. With that said, allowing the same context to have two different values seems like a confusing concept to wrap your head around, so maybe signals are better in this respect too.Anyway, something to consider when it comes time to document contexts - perhaps we'd want to push the signal pattern instead.
rmorshea commentedon Jan 8, 2023
The reasoning behind my assertion that signals are better comes down to two factors:
rmorshea commentedon Mar 8, 2023
More reasons to use signals over standard hooks: https://emnudge.dev/blog/react-hostage#fixing-react
I'm realizing that signals could actually be better than the standard
use_statehook if integrated a bit more into ReactPy's core layout rendering logic. Instead of re-rending a whole component, if you pass a signal directly as a prop or child of an element, ReactPy could intelligently update the value for you without requiring the whole component to re-render.For example, this would cause an infinite loop:
However, with signals...
The component
RendersOncewould, as the name suggests, only render once. Nonetheless the<p>element would receive a single update after the expected delay.VatsalJagani commentedon Jul 14, 2023
@rmorshea
You meant this right?
count.value instead of signal.value.
rmorshea commentedon Jul 14, 2023
Correct.
Archmonger commentedon Feb 3, 2025
When we develop this it's probably best situated as a external package, since it deviates from the
ReactJSAPI.Would also be a good excuse to start digging into whether we can make the renderer support user extensions.