-
Notifications
You must be signed in to change notification settings - Fork 6
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
Idea: Type-aware linting #40
Comments
Why shouldn't obj be allowed? I have fully legimitate use cases which can't be replaced with other ways, and there's a POC which fixes this. Disallowing this would conflict with the official react linter. |
I understand why we wouldn't want to monitor objects and only primitives instead since the renders for objects would be hard to manage but still, are we sure we wanna move forward with blocking that? as @sarimarton said, would actually conflict with the official react linter |
Passing snap object to useMemo (and all others) deps and also React.memo will break tracking property usage, because React will skip touching properties on next render. I think I've created a simple breaking app before, but can't find it now. So, we must destructure snap objects into primitive values in render function. I don't think it will conflict with react linter. Some old discussions: pmndrs/valtio#301 pmndrs/valtio#322 |
Objects are needed in equality checks. useEffect(() => {
fetch(api).then(response => { store.foo.bar = response })
}, [store.foo]) // <--- react linters mandates this The tracker shouldn't rely on object/primitive distinction. Now the tracker triggers on the most specific keys' value change + content change. (By content I mean any descendant key.) This makes it non-deterministic on the individual usages. Content change should be taken out of the picture. A few examples:
should trigger only when
should trigger only when With this algorithm, a key reference's tracking is non-deterministic based on whether a subkey will be referenced later. The latest version of useProxy fixes 3 problems, and I think those ones as well which you linked:
The only outstanding issue is the above design decision (which is maybe related to caveat 2) in the tracking logic, for that I'd need to write a new tracker :) (Which is not impossible btw, my next step would be to subscribe to shallow changes on line 31 of utils.ts. The only problem is that there's no shallow subscribe API) |
how would you know if both |
I shouldn't need know it. I should listen on |
doesn't |
It wouldn't. The current |
I'm confused. Not sure if we are on the same page. useEffect(() => {
console.log('this should fire when foo.bar.other is changed');
if (foo.bar.baz) {
console.log('baz is truthy.');
} else {
console.log('baz is falsy.');
}
}, [foo.bar]) |
Give me a shallow subscribe API, and I'll remove useSnapshot from under useProxy, and everything will be perfect 😉 |
No, that should only fire when foo.bar's value changed with a strict equality check. That's idiomatic react. Deep subscribe is the root of evil. In a tracking context, deep subscribe is bad. |
It only calls callback, when proxy.foo.bar gets reassigned to newVal, and newVal !== oldVal. It doesn't matter if it's an object or primitive value. |
if you mean you don't use but, anyway, what's your shallow subscribe look like? |
For now, you can simulate it with this: const unsub = subscribeKey(proxy.foo, 'bar', callback) |
Cool, I'll give it a try! |
Could you give me a hint why? |
without snapshots, two components rendered from parent will produce different results. It's why "reading" useRef is prohibited in render, and why If I understand correctly, what you are trying may work in legacy rendering, but not in concurrent rendering as we want. snapshot is the reason why valtio exists. It's not hypothetical, but hard to reproduce. you can see my contrived demo in https://www.youtube.com/watch?v=oPfSC5bQPR8 |
That was a great video, @dai-shi, and it enlighted me about your mindset on the design of Valtio. Thanks! A few observations:
|
I get your point and there might be something that I can re-consider, while I still believe the snapshot is crucial for valtio internals (but could be hidden from users.) I'll challenge you from another aspect. So, look forward to your experiment. |
After discussing in pmndrs/valtio#635, I understand that what it means by conflicting with react linter, or I'd say conflicting with react best practice. And, that's exactly the point of having the rule in eslint-plutin-valtio. |
Somewhere (there #16 (comment)), we discussed the limitation of linting because we can only analyze code statically.
If we could use type information, we could make linting better.
I stumbled upon eslint-plugin-functional which utilizes types.
We should be able to detect this:
Related: pmndrs/valtio#633 (comment)
cc: @barelyhuman @sarimarton
The text was updated successfully, but these errors were encountered: