question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Question: when does selector re-compute

See original GitHub issue

Imagine I have bunch of atoms:(all numbers)

const a = atom(...);
const b = atom(...);
const c = atom(...);

and a selector like below:

const s = selector({
  key: uniqueKey,
  get: ({get}) => {
     cobst aVal = get(a);
     const bVal = get(a);
     const cVal = get(a);

     return aVal+bVal+cVal;
  }
});

Now if on click of a button we call the following:

const clickHandler1 = useRecoilCallback(({set}) => () => {
  set(a, 1);
  set(b, 1);
  set(c, 1);
});

vs.

const clickHandler2 = useRecoilCallback(({set}) => async () => {
  set(a, 1);
  set(b, 1);
  --- await an asyc call here --- 
  set(c, 1);
});

How many times the selector s gets recomputed. Does the useRecoilCallback act as transaction? If not, how can one make updates to atoms transactional.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
drarmstrcommented, Oct 14, 2020

As @mondaychen indicated, useRecoilCallback() is intended for the synchronous execution to act as a transaction and will modify the Recoil state atomically and attempt to batch the updates for a single React render. With the await it will simply resume execution when the await resolves or throw if it rejects for a new transaction. You should not see a selector evaluation where a was set and b was not. (File a bug if you do 😉

However, that said, the selector could still be executed multiple times if any of the dependencies are themselves async. If those dependencies are still pending when it attempts to re-evaluate, then it will abort execution and retry again from the beginning when that dependency resolves or rejects. This follows the same semantics as React Suspense. In general, there is a contract that selector evaluation functions are idempotent and have no side-effects (other than caching, logging, and similar exceptions 😉 The selector evaluation may also be cached and/or the cache may be invalidated. You should not make any assumptions as to how many times a selector is evaluated.

0reactions
hatpickcommented, Oct 15, 2020

Thanks for the explanation @drarmstr @mondaychen I did observe the behavior via console.log, it was weird to see that for updates via set(atom, callback) it batches the updates but when there is an async call it doesn’t, so I asked the quesiton. I’m coming from a mobx background and I was expecting a util transaction function to manually batch operations (sync and async). Without it, a selector such as above will need lots of checking to prevent throwing due to undefined/null/etc. values for dependencies.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reselect selector keeps recomputing with the same input
Selectors created with createSelector have a cache size of 1. This means they always recalculate when the value of an input-selector changes, as ......
Read more >
Common Reselect Gotchas | Blog
Any time an action is dispatched that doesn't change state.todos we won't have to recompute the list of sorted todos, and that is...
Read more >
Understanding Javascript Selectors With and Without ...
category === 'pants' . This is a problem because Reselect selectors have a cache size of 1, which means that in this case...
Read more >
Redux Selectors: A Quick Tutorial
A selector is a small function you write that can take the entire Redux state, and pick out a value from it. You...
Read more >
Performant Redux Selectors with Reselect
Selectors created using Reselect's createSelector function are memoized. That's a fancy word to mean that the function remembers the arguments ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found