-
-
Notifications
You must be signed in to change notification settings - Fork 260
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
Possible to wrap snapshot and state into one? #38
Comments
Just saw your reply on twitter to this @dai-shi and makes sense. This may make supporting Valtio tough for JSX Lite or not possible sadly, but will keep thinking on and open to any ideas you have here (if any) |
A bit of context: For example: const state = proxy({ a: 1, b: 2 })
const Component = () => {
const snapshot = useProxy(state)
return <div>{snapshot.a}</div>
} This component only re-renders if Now, I first thought your idea of However: const combined = onChange(snapshot, (path) => set(snapshot, path, state))
combined.a // tracked 'a' usage
combined.b = 3 // this is also tracked as 'b' used So, the component will re-render if Again, the confusing behavior is: combined.b++ // internally state.b becomes 3
combined.b++ // the state.b is still 3
console.log(combined.b) // will show 2... There might be a better way that I don't consider now. The current behavior requires user to understand the difference between immutable
That's unfortunate. (btw, I like the idea of JSX Lite very much.)
Let's keep this issue open for a while and see if anyone is interested in investigation. |
Thanks for the detailed info @dai-shi - really appreciated. All makes a lot of sense here. I'll continue to stew on if we can make this work. I also realized I could also better illustrate our challenge as well if you have any ideas import { useState } from '@jsx-lite/core'
export default function MyJSXLiteComponent(props) {
const state = useState({
getProductName(product) {
// Needs to be snapshot, but we don't really know what `product` is at compile time to make that swap
return product.name;
},
setProductName(product, name) {
// Needs to be `state`, but we don't really know what `product` is here at compile time either
product.name = name
}
})
return (
<div onClick={() => {
// Right here, to the compiler, this appears like it should be using `snapshot` bc it's accessing a value, but that's wrong as it's only to pass to a helper to mutate the value, so it needs to be using `state`
state.setProductName(state.products[0], 'foobar')
}>
{state.getProductName(state.products[0])}
</div>)
} |
// Right here, to the compiler, this appears like it should be using `snapshot` bc it's accessing a value, but that's wrong as it's only to pass to a helper to mutate the value, so it needs to be using `state`
state.setProductName(state.products[0], 'foobar') This is fine. We should just read from (I'm still not sure if I fully understand the challenge, though. As I'm interested in your compiler approach, I'd like to take a closer look when I got chance.) |
Since |
Well, this is a discussion on top of useLocalProxy. Anyway, the original question is answered, so let's close this. We can continue discussing alternative ideas here, or create a new issue. |
With JSX Lite we hope to support Valtio, but there is one outstanding issue now that I understand the separation between state and snapshots which is that we don't always know at compilation time if a read or write will happen. This is because references can be grabbed and passed to functions as arguments, and the functions may do reads and writes on objects that we don't know at compile time what they trace back to
So if we could just have one object returned that can be read and written to, that would resolve this challenge . For instance this could be done with the help of a couple libraries like
on-change
andlodash
, in theory, roughly like the belowbut if Valtio supported this, e.g. as an optional util, that would allow us to support it properly and be easy for those coming from mobx etc (or like the elegance of not having to think of state vs snapshots and just treat the proxy like a plain mutable object)
The text was updated successfully, but these errors were encountered: