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.

`<Async.Fulfilled>`'s function gets called with a mix of old&new data on subsequent updates

See original GitHub issue

Hi. This seems like a new case for #8 , except that one was closed based on side effects in render. Here we have a valid side-effect in componentDidUpdate that gets triggered unexpectedly.

Essentially, we have a

loadRootEntityAsync({ rootEntityId }) {...}

render:
              <Async
                promiseFn={this.loadRootEntityAsync}
                rootEntityId={rootEntityId}
              >
                <Async.Fulfilled>
                  {rootEntity => (
                    <RootEntity
                      rootEntity={rootEntity}
                      selectedChildEntityId={selectedChildEntityId}
                    />
                  )}
                </Async.Fulfilled>
              </Async>

Note that selectedChildEntityId can be null, when the user doesn’t navigate using a precise URL, but then there’s some logic in <RootEntity> that will select the appropriate child entity - this logic happens in <RootEntity>'s componentDidUpdate.

So, it works perfect on the show of the first root entity, but when user navigates to another root entity (by changing rootEntityId and setting selectedChildEntityId to null), the old <Async.Fulfilled>, just before the <Async.Pending> for the new fetch, gets another invocation with the old rootEntity, and empty selectedChildEntityId, which triggers a new finding of selectedChildEntityId, resetting the user navigation. This is the usual shape of the problem, but if the user navigates straight to a specific selectedChildEntityId (e.g. using browser back button or using a direct link) it will result in creating a component tree where the new child entity is in the context of an old root entity. This, will throw an error in the best case, but might as well cause corruption, depending on what the components do in their lifecycle methods.

For now, the workaround is to use <Async key={rootEntityId}>, a common technique for preventing components reuse, which prevents that last unnecessary firing of the <Async.Fulfilled>'s function.

It seems though this could be prevented elegantly by preventing the render of the <Async.Fulfilled>'s function the moment the arguments to promiseFn change. Instead of that one, <Async.Pending> could be used in this render, which, semantically, seems to be even more correct - another execution of the async action is imminent.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
ghengeveldcommented, Jul 25, 2019

Hey Slawomir, I’d love to slightly optimize React Async’s behavior to account for this scenario. However I don’t have the time to really dive in. Could you at least provide a minimal reproduction of the issue?

I also think you might be able to avoid the issue altogether with useAsync, where you have full control over component rerendering. Have you tried that?

0reactions
gamlielacommented, Nov 26, 2021

I have the same problem, but with the useAsync hook. After changing the promise in the hook, I’m getting back the old data (of the previous promise). Any plans to fix this? Seems pretty critical IMO! I’m not sure about the status of this project, but if still maintained I can try and contribute a PR to fix it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Async/Await doens't wait for the previous function to complete
That being the case, I need to wait until the previous call is completed before continuing. Is async/await not the correct way of...
Read more >
SchedulerPro/view/ResourceHistogram - Bryntum
This widget displays a read-only timeline report of the workload for the resources in a project. The resource allocation is visualized as bars...
Read more >
ETSI TS 102 221 V6.1.0 (2003-06)
TIPHONTM and the TIPHON logo are Trade Marks currently being ... Functional parameters . ... Latest updates are available on the ETSI Web....
Read more >
What's New for Visual Basic in Visual Studio 2022 - .NET Blog
NET Framework or for the latest version of .NET. Overall. Visual Studio 2022 has a new look, with the new Cascadia font and...
Read more >
RFC 2967 - TISDAG - Technical Infrastructure for Swedish ...
Supported Query Types The DAG system is designed to support fragment-matching queries on a limited set of data attributes -- "Name", "Organizational Role", ......
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