Skip to content
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

Listen to deep $state changes like $inspect but in prod mode? #15078

Closed
errmayank opened this issue Jan 21, 2025 · 10 comments
Closed

Listen to deep $state changes like $inspect but in prod mode? #15078

errmayank opened this issue Jan 21, 2025 · 10 comments

Comments

@errmayank
Copy link

errmayank commented Jan 21, 2025

Describe the problem

Is there a proper way to listen to any deeply nested change in the $state object? Here's a minimal reproduction link

When you make changes to Name input it fires the console.log() but on changes to Method and URL nothing happens

If you comment out the $effect logic and uncomment $inspect one this works for all input changes and it would be ideal for me but it becomes a no-op in production build as stated in the docs

Can i do this without needing to explicitly add each key to the listenTo array in the repro?

Describe the proposed solution

$inspect but for production?

Importance

would make my life easier

@errmayank errmayank changed the title Listen to deep $state changes like $inspect in dev mode? Listen to deep $state changes like $inspect but in prod mode? Jan 21, 2025
@elliott-with-the-longest-name-on-github
Copy link
Contributor

If you want a quick-and-dirty solution, just JSON.stringify(value_to_track). It's definitely not efficient for massive values but if we're talking small ones, it'll trigger changes on every property change since it recursively reads everything. Also doesn't work for recursive stuff.

@paoloricciuti
Copy link
Member

Also there's this proposal #15069 that will allow you to specify a callback on the state itself (but you have to own the state)

@errmayank
Copy link
Author

@elliott-with-the-longest-name-on-github nah, i'd rather add each key separately to the listenTo array than unnecessary serializing the state like that but thanks

@errmayank
Copy link
Author

@paoloricciuti this looks great! by owning the state do you mean like the global exported state in the repro above and it can't be a passed prop or something?

@paoloricciuti
Copy link
Member

@paoloricciuti this looks great! by owning the state do you mean like the global exported state in the repro above and it can't be a passed prop or something?

I mean that you can't do this with a prop for example...it has to be declared state

@brunnerh
Copy link
Member

$inspect is pretty much just an $effect.pre that uses $state.snapshot on the values.
You can do the same in your code (though the variable should be renamed from state to something else, otherwise you get errors).

Playground

@errmayank
Copy link
Author

Great! thanks @brunnerh. Just one more thing, would this $state.snapshot cause any performance hit compared to @paoloricciuti's onchange listener which applies on the $state itself?

@paoloricciuti
Copy link
Member

Great! thanks @brunnerh. Just one more thing, would this $state.snapshot cause any performance hit compared to @paoloricciuti's onchange listener which applies on the $state itself?

Yes, $state.snapshot will traverse the whole object and $effect has a bit of overhead too... nothing really to be preoccupied but if that PR lands it will probably be better to use that if possible

@Thiagolino8
Copy link

Also $state.snapshot uses structuredClone under the hood, which is MUCH less performant than JSON.stringify when you just want to read the values

@paoloricciuti
Copy link
Member

I'm gonna close this since it's already doable in some way or another...thanks for reporting

@paoloricciuti paoloricciuti closed this as not planned Won't fix, can't repro, duplicate, stale Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants