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

[Suggestion] Display Warning/Error When Using Proxy Instead of Snapshot for Comparison in useEffect #52

Open
GorvGoyl opened this issue Oct 18, 2024 · 7 comments

Comments

@GorvGoyl
Copy link

Sometimes, I mistakenly use a proxy inside useEffect for comparison, which leads to unexpected errors. I wish there were a way to display a warning if I try to use a proxy inside useEffect for comparison.

@dai-shi
Copy link
Member

dai-shi commented Oct 19, 2024

Thanks for opening up an issue.
Can you write some small code snippets to illustrate the problem?

@barelyhuman
Copy link
Collaborator

The plugin doesn’t do cross file scopes so if your proxy comes from a different file the rule would become useless.

we do currently assume that a variable is a proxy if it’s passed to ‘useSnapshot’ but if you use the proxy without the snapshot creation then the rule wouldn’t know what to do.

let me think further if there’s a better way to avoid the issue

@GorvGoyl
Copy link
Author

@barelyhuman thanks, I hope there's a way!

@barelyhuman
Copy link
Collaborator

barelyhuman commented Oct 23, 2024

So after trying out a few approaches, the only viable cases are

  1. is if the proxy is added to the snapshot
  2. or the proxy import is available in the same file.

Proxy being imported from another file (Cross file references) will create a lot of scoping management which will slow down the plugin and we'd have another typescript language server situation.

Though, if I understand the problem you need something that notifies you of whether you accidentally put the proxy in use effect.

import {proxy, useSnapshot} from "valtio" 

const proxyState = proxy({count:1}) // => We now know that `proxyState` is a proxy

function Component(){
const snap = useSnapshot(proxyState) // => Also signifies that `proxyState` is a proxy

useEffect(()=>{
 // can now detect if proxy state is in here. 
},[])

return <></>
}

If one of the above is satisfied, we can throw a warning.

also, if there's a function inside the effect that's using the proxy, there's cases where it might be valid and cases where it might not be so that makes it invalid to throw a warning.

function Component(){
const snap = useSnapshot(proxyState)

useEffect(()=>{
 const update = ()=>{
     proxyState.count += 1
  }
  let id = setInterval(()=>{update()}, 1000)
  return () => clearInternval(id)
},[])

return <></>
}

in the above case the usage is valid so that will not have a warning.

@dai-shi want to add any other cases where it might valid/invalid to use the proxy ?

@GorvGoyl
Copy link
Author

if I understand the problem you need something that notifies you of whether you accidentally put the proxy in use effect.

yes that's correct.

if there's a function inside the effect that's using the proxy, there's cases where it might be valid and cases where it might not be so that makes it invalid to throw a warning.

I'm not sure if eslint could do it but here's one approach:

useEffect(()=>{
// don't show error if operation is mutation 
  proxyState.count += 1
},[])

useEffect(()=>{
// show error if operation is comparison
  if(proxyState.count>1){
}
// show error if operation is accessing a value
const usageQuota = proxyState.usageQuota;
},[])

If the above is not possible, one idea is to show a warning (instead of an error) if a proxy is present inside useEffect. This should prevent most mistakes, if not all. The likelihood of a practical scenario where a proxy value needs to be updated inside useEffect is quite low, I suppose.

@barelyhuman
Copy link
Collaborator

barelyhuman commented Oct 24, 2024

it is possible to selectively show warning only for comparison/accessing, mostly worried about the detection of something being a proxy.

we already do selective warnings for snapshots

@dai-shi
Copy link
Member

dai-shi commented Oct 26, 2024

  // don't show error if operation is mutation 
  proxyState.count += 1

That seems a bit too hard, because it's both read and write...

I understand reading a proxy value directly in useEffect body is almost a mistake, but I'm not sure if there are valid cases. There can be.

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

3 participants