Recoil: Updating async selector state

Created on 31 May 2020  路  4Comments  路  Source: facebookexperimental/Recoil

Let's imagine the next real-life scenario:

  • I have a list of users to be loaded from some endpoint and displayed in my UI.
  • Then I need to edit one of them
  • And save my edits to the backend
  • And of course apply the same edits to the list displayed?

How do I implement this using Recoil? My first thought was:


const usersSelector = selector({
    key: 'users',
    get: () => fetch('https://my-site.com/users.json'),
    set: ({get, set}, updatedUsers) => {
        set(usersSelector, updatedUsers); // won't work
    }
});

This one does work, but is too wordy for my taste:

const usersAtom = atom({key: 'usersAtom'});
const usersSelector = selector({
   key: 'usersSelector',
   get: ({get}) => get(usersAtom) || fetch('https://my-site.com/users.json'),
   set: ({get, set}, updatedUsers) => {
        set(usersAtom, updatedUsers);
   }
});

So my proposal is to fix the first approach by allowing selectors to 'self-set' the values.

question

All 4 comments

Hi @karevn

You could use a promise to initialise your atom. And being an Atom it can also be _written_ to so I think that would work for your situation.

const userAtom = atom({
  key: 'user',
  default: fetch('https://my-site.com/users.json')
});

Issue #149 describes a similar situation, so you might find some of the answers in there helpful too.

Thanks for your suggestion! It looks like async-initialized atom is exactly the thing needed!

Hi @karevn

You could use a promise to initialise your atom. And being an Atom it can also be _written_ to so I think that would work for your situation.

const userAtom = atom({
  key: 'user',
  default: fetch('https://my-site.com/users.json')
});

Issue #149 describes a similar situation, so you might find some of the answers in there helpful too.

How does one set async state after the atom was initialised, but also find out if the request is either 'loading', 'hasContent' or 'hasError',聽there seems no way to do that?

Hi @stephanoparaskeva

How does one set async state after the atom was initialised,

Setting state would be the same as an Atom that was initialised synchronously.

find out if the request is either 'loading', 'hasContent' or 'hasError',

useRecoilValueLoadable will give that information.

Was this page helpful?
0 / 5 - 0 ratings