Setter for async selector #1890
-
Hi all 👋 , How would you go about handling this use case? I have an async selector that retrieves a list of accounts
If I now want to create a new account, after successfully creating the account, I want to change the state of It doesn't seem possible to add a setter for this selector. How have folks handled this use case? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
Here's a few approaches I can think of, each with their own tradeoffs: /**
* Method 1: Atom with promise as default (will fetch immediately)
*/
const recoilAccountsState = atom({
key: 'recoilAccounts',
default: recoilAccountsApiCall(),
});
set(recoilAccountsState, (accounts) => [...accounts, newAccount]);
/**
* Method 2: Atom with selector as default (will fetch lazily)
*/
const recoilAccountsState2 = atom({
key: 'recoilAccounts',
default: selector({
key: 'recoilAccountsSel',
get: () => recoilAccountsApiCall(),
}),
});
set(recoilAccountsState, (accounts) => [...accounts, newAccount]);
/**
* Method 3: Bi-directional selector (will fetch lazily)
*/
const localAccounts = atom({
key: 'localAccounts',
default: [],
});
const recoilAccountsState3 = selector({
get: async ({get}) => {
const localAccounts = get(localAccounts);
if (localAccounts.length) {
return localAccounts;
}
return recoilAccountsApiCall();
},
set: ({set}, newAccounts) => set(localAccounts, newAccounts),
});
set(recoilAccountsState3, (accounts) => [...accounts, newAccount]);
/**
* Method 4: Atom Effect (will fetch lazily)
*/
const recoilAccountsState4 = atom({
key: 'localAccounts',
effects: [
({setSelf}) => {
recoilAccountsApiCall().then((accounts) => setSelf(accounts));
},
],
}); Methods 3 & 4 would be the most powerful (but also the most complicated) as you can customize the logic for when accounts should be re-fetched from the server if you need to refetch, where as Methods 1 & 2 will have their atom value replaced as soon as you set the atom and you'd have to handle re-fetching separately. I wouldn't recommend Method 2 as I've seen it lead to confusion and bugs |
Beta Was this translation helpful? Give feedback.
-
Thanks for the suggestions Christian. I think 3 may work best for our use case, however I think it's unclear where the atom would be set. Atom's are not able to subscribe to data changes. Our specific use case requires us to be able to reset the state when the page reloads. As you mentioned for this case, we would have to write custom logic that sets and resets the atom state Ideally, we would want the setting of the atom state to live inside of Where would the setting of the atom live in this case? |
Beta Was this translation helpful? Give feedback.
Here's a few approaches I can think of, each with their own tradeoffs: