-
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
False positive for "Better to just use Proxy state" without separate assignment #16
Comments
thanks for reporting! The first one is not a safe practice. It might not work in some cases. The second one 👇 seems like a real issue for
The third one seem a safe practice, it would be nice if lint can pass it. The forth one 👇 sounds weird.
|
@barelyhuman would you be interested in digging this?? |
@dai-shi Makes sense, but I tend to treat even lint warnings as something to avoid, otherwise I prefer to disable the rule 😆 . Linter noise can condition devs to ignore the warnings completely if they are not high-value.
🤭 Can you help me understand why? Is that because the dependency array of // executes ok, lint notok
function useExample0(s: typeof state) {
const snap = useSnapshot(s.a1);
useEffect(() => {
if (snap.b.c === 'a1c') {
state.a1.b.c = 'example';
}
}, [snap.b.c]);
}
I think this is because I was ambiguous and also guessing! I didn't mean the |
Yes, this ☝️ is safe because deps array only has primitive values.
ah, okay. yeah, it tracks property usage, so changing |
Sure, I'll pick this up |
So, to confirm
anything else that needs to be added as a test case ? |
@barelyhuman Example1 is something we need to fix. Example2 is something nice to fix. |
It turns out that it's extremely difficult to catch edge cases, because a) we can't know if a property of an object is a primitive value or another object, and b) we can't know if a prop in a component or an argument in a hook is a proxy object or a snap object. |
@dai-shi when this fix is being released? Yesterday only removed this plugin, due to this issue. |
@Aslemammad will be working on something before releasing it. (edit: it's released.) https://ci.codesandbox.io/status/pmndrs/eslint-plugin-valtio/pr/17/builds/221434 |
EDIT: apologies for this disjointed reply, I hadn't refreshed the page before responding. Thank you fixing the issues that could be fixed!
Are snap objects not comparable between component renders? I understand why the lint rule would be confused, but not why the usage of a snap in a useEffect dependency array would be unsafe. Or is it that valtio does not track property usages that resolve to objects, only primitive values?
WOW I didn't know this. Pretty incredible! So just to be clear, two components that useSnapshot at different levels: const snap = useSnapshot(state.nested.property)
snap.something; and const snap = useSnapshot(state)
snap.nested.property.something; ... will both rerender the same number of times? |
No, it's because React will access properties conditionally.
Objects work fine. It's just "leaf" usage is tracked.
In terms of the number of re-renders, yes. The former is preferable, because the subscription is more scoped (narrower). |
Ok, all makes sense. Thank you for the explanation! |
Hello, thanks for making this plugin, it's been helpful while learning valtio!
I believe I've found a bug 😅
In the following example, the goal is to get the
useExampleX
hook'suseEffect
callbacks to execute when one of the watched properties changes, and without a parent component passing in a new version ofstate
. An additional goal is that only whena1
's properties change would the hook rerender.It's unclear exactly what is happening. The bug seems to be triggered by destructuring directly from
useSnapshot
or directly referencing the snapshot in theuseEffect
. Or is it that assignment of the snapshot defeats the lint rule?A worrying aspect is that if a developer blindly followed the recommendation from the linter, it would produce code that does not behave as expected. It's somewhat obvious in these contrived examples (
useExample1
), but is less obvious in a larger codebase with multiple layers of hooks.A workaround for now appears to be:
useSnapshot(state.a1)
on the parent you needThe text was updated successfully, but these errors were encountered: