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.

Atom effect onSet() causing infinite loop

See original GitHub issue

In the atom effects documentation - it is noted that the onSet() listener will not be called due to changes triggered from setSelf()

// The callback is not called due to changes from this effect’s own setSelf().

I seem to be getting an infinite loop when using setSelf() - but maybe I’m missing something important.

I have created a contrived example on codesandbox which adds random numbers and illustrates the behaviour.

Edit Atom Effects Random Adder Causes Infinite Loop

Cheers

B

Issue Analytics

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

github_iconTop GitHub Comments

1reaction
drarmstrcommented, Nov 17, 2020

Atom effects aren’t intended to act as middleware. They allow you to observe sets, but not intercept and modify a value before it is being set. So, if you observe a set an initiate a new set it can cause a loop. Atom sets are queued, so you can’t guarantee if the effect observation handlers are called before or after other components see the new value, though we reserve the ability to make guarantees and maybe allow this in the future.

If you want a temporary value while something is pending you could use useRecoilCallback():

const startAThink = useRecoilCallback(({set}) => async () => {
  set(myAtom, pendingValue);
  const newValue = await fetchLongRunningThing();
  set(myAtom, newValue);
});

or maybe wrap with a selector

const wrappedState = selector({
  key: 'MyWrappedState',
  get: ({get}) => {
    const longRunningLoadable = get(noWait(longRunningSelector));
    return longRunningLoadable.state === 'hasValue'
      ? longRunningLoadable.contents
      : pendingValue;
  },
});
1reaction
justintomancommented, Nov 8, 2020

That is what will happen if you kick off the long running async process from inside the onSet handler. The value will be eagerly set, and then some async thing will happen.

Although, I’m not sure how error handling is supposed to work. If I update my atom with an invalid state and my server responds with a 400 (or the service is down or messed up and I get a 500), how am I supposed to revert the change back to the previous valid value?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Atom Effects | Recoil
Atom effects are an API for managing side-effects and synchronizing or initializing Recoil atoms. They have a variety of useful applications such as...
Read more >
Why did switching to from an infinite loop to TimerTask cause ...
Three possibilities I can think of: You have a huge number of threads doing this, and they're context switching all the time.
Read more >
locking | The Infinite Loop
Crucial for the scalability of spinlocks is the amount of cache line invalidations which take place when the lock is acquired and released....
Read more >
Can an infinite loop in Python damage the computer's ... - Quora
No. It might, at the worst case, “hang” the os by overconsumption of resources (either filesystem or processing time or memory). But that...
Read more >
Why useEffect causes infinite loops - fix it with useCallback
Just a little example of how to fix an infinite useEffect loop caused by fixing a eslint exhaustive-deps warning------------ Newsletter ...
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