-
Notifications
You must be signed in to change notification settings - Fork 153
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
Reactivity v3! (Part 1) 🎉 #612
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #612 +/- ##
==========================================
+ Coverage 62.21% 66.90% +4.69%
==========================================
Files 54 63 +9
Lines 9408 11168 +1760
==========================================
+ Hits 5853 7472 +1619
- Misses 3555 3696 +141
☔ View full report in Codecov by Sentry. |
Co-authored-by: Genna Wingert <[email protected]>
Hey @wingertge, I included the docs you wrote from #601 in this PR and I added you as a co-author. Hopefully you don't mind! |
361fd7a
to
675a252
Compare
I will be merging this now since there is already quite a significant amount of changes. The remaining work of migrating the rest of the Sycamore code base to use the new reactivity system will be done in a different PR so as to not make this one bigger than necessary. |
A brand new implementation of Reactivity!
This gets rid of all the lifetimes introduced in #337 while maintaining the ergonomics of not having to
clone
everything into every closure.Most of the API surface still has the same form, except without the lifetime annotations.
A few APIs, however, need to be changed or removed all together, including
create_ref
andprovide_context_ref
. This is because these APIs internally relied on the arena allocator attached to each scope which has been removed completely.Instead, you can just use
create_signal
andcreate_context
instead.Another API that has been removed completely is
RcSignal
. SinceSignal
s are'static
now, we can just include them directly in whichever state we want without any lifetime woes. However, this comes at the risk of accessing a signal beyond its "runtime-lifetime", i.e., it can still be accessed even after the scope is dropped, causing the app to immediately panic. In practice, however, these situations are rare enough that they justify the added ergonomics of removing lifetimes.One tricky part is when collections are involved with signals. The current design of Sycamore encourages using nested signals for fine-grained updates. This, however, is no longer a good solution with the new reactive primitives. This is because if we
create_signal
and insert the result into, say, aVec
, theSignal
will not be dropped until the enclosingScope
is dropped. Suppose we now want to remove a row from theVec
. TheSignal
, however, will keep on holding onto its data which essentially causes a memory leak.Leptos solves this issue by adding a
.dispose()
method onSignal
s so that you can manually clean up after yourself when you removeSignal
s from aVec
. I believe, however, that this approach is error-prone and boilerplate-y. Instead, I propose introducing a new "Store-API" modeled on SolidJS'screateStore
primitive. This would get rid of the need all together to have nested signals. Instead, everything can be kept inside a normal Rust data-structure wrapped inside aStore
which would keep track of reactive gets and sets with fine-grained updating.Edit:
Upon further consideration, I've decided to remove the explicit reactive scope tracking with
cx: Scope
in favor of implicitly tracking it. This brings the function signature back to the pre-0.8 style of:instead of:
which I believe is much nicer.
Remaining tasks:
Implement the Store API(Part 2?)Root
system should work on the server-side. Introduce aRootPool
?Migrate the entire Sycamore codebase to the new reactive system(Reactivity v3 (Part 2) #626 )