Nozbe / withObservables

HOC (Higher-Order Component) for connecting RxJS Observables to React Components
https://github.com/Nozbe/WatermelonDB
MIT License
68 stars 26 forks source link

Loading state in rendered component #10

Open sebastian-schlecht opened 6 years ago

sebastian-schlecht commented 6 years ago

We're seeing quite some "flickering" due to null being rendered when data is fetched. We are aware of the fact that, in general, this is a hint that queries are made to often, however sometimes we have quite complex queries to make where the "delay" incurred by fetching data is in fact noticeable. A solution could be to pass down the isFetching state to the component being rendered in order to display a loading state or similar. Debouncing could still be done downstream if necessary.

We would be willing to contribute this as a PR here.

radex commented 6 years ago

@sebastian-schlecht Hey! This is a known problem for us, right now impossible to avoid with asynchronous calls, and we should really document how to deal with this:

  1. We have a small Prefetcher class that loads all the necessary queries BEFORE a view is shown. Because of 🍉 caching, when the actual components wants to fetch a query, it gets the answer synchronously.
  2. You can make much of the flicker less obvious in lists by making the asynchronous calls on a list element a separate component. E.g. if you have a list with a name and a counter, the list will render immediately after the list query is resolved, but counters are part of a mini-component, so its delay doesn't block rendering of the whole list component
  3. Soon we'll have React ConcurrentMode and Suspense which will allow us to magically hide the async delays. The components will render when ready, and you'll be able to add a suspense placeholder if it's taking longer than, say, 300ms.

Does that help? Is your issue that it's actually taking too much time to load data, or just the visual ugliness of flicker? If the latter, prefetching should do the job much more nicely than a placeholder. I could open source the Prefetcher code and give you some guidance if you could help write it up in Watermelon docs

sebastian-schlecht commented 6 years ago

I would be really interested in your Prefetcher code, as it might simplify our current setup. We used React's Context API because we weren't aware that data is loaded synchronously when inside the cache.

You can make much of the flicker less obvious in lists by making the asynchronous calls on a list element a separate component. E.g. if you have a list with a name and a counter, the list will render immediately after the list query is resolved, but counters are part of a mini-component, so its delay doesn't block rendering of the whole list component

So basically your advice is to put queries closer to their actual presentation? This could work for us as well if I think about it...

radex commented 6 years ago

I would be really interested in your Prefetcher code, as it might simplify our current setup. We used React's Context API because we weren't aware that data is loaded synchronously when inside the cache.

as long as some component (or a Prefetcher) is observing a query, the next component will get the result for free instantly. I'll share the code soon

So basically your advice is to put queries closer to their actual presentation? This could work for us as well if I think about it...

yeah! It's not perfect, but in many cases makes the glitch invisible, and you're blocking the render of only a small portion of the whole component tree

radex commented 6 years ago

@sebastian-schlecht check this out:

https://gist.github.com/radex/9759dc1ea23a25628b80ed06f466264f

This is copy&pasted quickly from our project. You can adapt it to your needs in your project, but it would be awesome if you helped actually include it in Watermelon core. This mostly needs cleaning up and writing up a quick documentation file for.

Does this help?

radex commented 5 years ago

@sebastian-schlecht did you have a chance to look at this?

sebastian-schlecht commented 5 years ago

Unfortunately I haven't. We're in the process of releasing right now so there hasn't been time. We've come around the original issue via moving the query closer to the presentational component as you suggested.

radex commented 5 years ago

OK, Cool, No pressure — Just let me know if you want to tackle this in the future