facebookexperimental / Recoil

Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.
https://recoiljs.org/
MIT License
19.6k stars 1.19k forks source link

[Question] Referencing last state on selector #326

Closed plumsirawit closed 4 years ago

plumsirawit commented 4 years ago

Consider a hypothetical scenario when I have an atom AState (used to represent some text) and a selector BState which has a logic like this:

For example, let AState has the default value of 0, now the BState is 0. When I trigger set state of A to 2, BState will be 4. But when I set AState to Hello, world!, BState should renders 4 (as the last thing it returned before).

As a direct attempt, I tried to use get(BState) directly inside the get function of the selector, but it turns out like Uncaught Error: Recoil selector has circular dependencies.

After a little thinking, I come up (but still not sure) with a solution of using two atoms, one for current value (let's call this currentAState) and the other one for last valid value (let's call this latestValidAState) and let BState reference a derivation of currentAState if it is valid, or latestValidAState otherwise. But I think this solution does not utilize the benefits of recoil.

So my questions are:

drarmstr commented 4 years ago

If a selector is referencing previous executions, then that would actually represent additional state; selectors are really only functions of derived state, and not state themselves.. Select functions are "pure" or "idempotent" at a high-level concept. The output of the function should always be the same for a given set of input dependency values. We can't make guarantees about how many times it is executed or the order of execution. Using another atom to store "last valid" state or something would be a reasonable way to handle this. You can also use the set of your selector wrapper to set both atoms with valid state changes.