https://codesandbox.io/s/recoil-counter-demo-9uir6?file=/src/App.js
Comment out the setTimeout line and it works fine
I think you have to call get first, to register the dependency on the countState atom before doing anything asynchronous. If I implement it like below, it works for me.
get: async ({ get }) => {
const count = get(countState); // register dependency on countState
await new Promise(res => setTimeout(res, 2000));
return count + 1;
}
Hmm, so the selectors can't have an async element to them in that case. Is there any way around that? This means that if I wanted to have if/else logic in the selector, I can't make the function async before that selection. Is there some way to get both async and conditional deps?
This is a known bug that we are working on. Thanks for reporting and nice find!
(The bug is that only dependencies that happen during the initial synchronous execution of the selector are recorded.)
Hey there @davidmccabe -I watched your talk! Great work on this whole thing and thank you for open sourcing it! Following it with great interest.
I've seen you mention in a few places still getting used to what works best for open source projects and GitHub in general. If I may offer a tip:
For bug reports like this that are "known issues", often times project maintainers choose to keep the GitHub issue "open", so that others who come can see that it's 1) known already 2) being worked on / if there are blockers or other decisions that need to be made, and 3) to let people interested in the bug "subscribe" to the GitHub issue thread to be notified of progress updates, or when it's fixed in a new release.
In looking through the closed issues for this project, I notice that there have been a few duplicate bug reports already- as this project grows, that's likely to continue. I'm sure the FB internal version of this codebase has its own bug or issue tracker, and that's okay (especially for a young open source project). GitHub issues are a natural way to encourage community participation, with their own culture and norms. As the community grows, best practices will evolve and develop!
Thanks again!
@junosuarez thanks for the tip!
I also ran into this problem, and maybe it is helpful to other people if I post my current workaround:
As @kolodny said and @davidmccabe confirmed, selectors can't have async operations inside them, if there is any get dependency after the await. So I guess what you'll have to do for now is to extract all async calls to a separate selector or atom.
I forked the example from above: https://codesandbox.io/s/recoil-counter-demo-zm93o?file=/src/App.js:202-395
I just replaced the setTimeout async part with an extracted selector (and added some randomness to indicate that it works):
const extractedAsyncState = selector({
key: "extractedAsyncState",
get: ({ get }) => {
get(countState);
return new Promise(res => setTimeout(() => res(Math.random()), 500));
}
});
Most helpful comment
This is a known bug that we are working on. Thanks for reporting and nice find!
(The bug is that only dependencies that happen during the initial synchronous execution of the selector are recorded.)