Recoil: async selector does not update when atom value used after await changes

Created on 17 Jun 2020  路  4Comments  路  Source: facebookexperimental/Recoil

sandbox!

My selector uses an atom, when I update that atom, I assume my selector should update as well since it uses it internally. Am I wrong?

bug duplicate

All 4 comments

You should separate the async query into a separate selector/selectorFamily and compose the two with a third selector, something like this:

const asyncPromise = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, 5000);
  });

const atom1 = atom({
  key: "atom1",
  default: 1
});

const selectorTest = selector({
  key: "selectorTest",
  get: async ({ get }) => {
    return await asyncPromise();
  }
});

const selector1 = selector({
  key: "selector1",
  get: ({ get }) => {
    const a = get(selectorTest);
    const valy = get(atom1);
    console.log({ valy });
    return valy;
  }
});

You should separate the async query into a separate selector/selectorFamily and compose the two with a third selector, something like this:

const asyncPromise = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, 5000);
  });

const atom1 = atom({
  key: "atom1",
  default: 1
});

const selectorTest = selector({
  key: "selectorTest",
  get: async ({ get }) => {
    return await asyncPromise();
  }
});

const selector1 = selector({
  key: "selector1",
  get: ({ get }) => {
    const a = get(selectorTest);
    const valy = get(atom1);
    console.log({ valy });
    return valy;
  }
});

If you use the get selector for Async actions, how do you update the state based on a response. i've asked this before but still don't understand.

get selectors allow you to get. Asynchronously as well.
how do you set? in an asynchronous way?

The idea is not to set, but to compose. If you have something that needs something else you bring them together into a new selector.

This can potentially get verbose when you have many stages, which is why I proposed #317. So you could just do something like const selector1 = atom1.zip(selectorTest).map((a,s) => a);

This lets you "fall into a pit of success" as it lets the process short circuit at any point in which the input(s) have already been given before.

Duplicate of #103

There is a known issue #103 that dependencies after an async callback or await will not be properly recorded. We have a fix in the works.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pesterhazy picture pesterhazy  路  4Comments

aappddeevv picture aappddeevv  路  3Comments

Etherum7 picture Etherum7  路  3Comments

yuantongkang picture yuantongkang  路  3Comments

Sawtaytoes picture Sawtaytoes  路  4Comments