- React Fundamentals
- React Hooks
- Advanced React Hooks
- Advanced React Patterns
- React Performance
- Testing React Apps
- React Suspense
- Build an Epic React App
NOTE: In the latest version of React, “Concurrent Mode” is not a thing. Instead there are “Concurrent Features” that your components opt-into via the concurrent APIs which you will learn about in this workshop. Learn more about some of the changes in the notice at the top of this docs page: https://react.dev/blog/2022/03/29/react-v18#gradually-adopting-concurrent-features
The new rendering behavior in React 18 is only enabled in the parts of your app that use new features.
“Render as you fetch”: kicking off the request for the data as soon as you have the information you need for the request.
Interesting createResource
refactor, check the code.
3 different ways we fetch in React
- Fetch on Render 👎: useEffect, fetch on it. (in the example,
<React.Suspense>
is only used for the lazy loaded component, not for the fetch). Waterfall effect: 1. Load the code. 2. Make the fetch. 3. Load the image the fetch data points to. - Fetch then render 👎: still useEffect and lazy loading the component, but the fetch happens in the parent (so it happens before the component loads). Fetch and component code could be loaded in parallel, but you probably don't render the component unless you have the data (unless using placeholders) so you could still have the waterfall.
- Render as you fetch 👍:
createPokemonInfoResource
(responsible for loading data) lazy loaded, component also lazy loaded. No waterfall.
React.Suspense will also render the fallback if the children components are being lazy-loaded
Use useTransition
to not show the fallback, for a few moments, instead you can
show something else in the meanwhile, like blur or opacity. Then if it's still
taking to long show the fallback eventually.
Consider using CSS transition-delay: 0.3s;
so fast connection don't see a
flickering blurr. Slow connection will have a 0.3s daley befor the blurr is
showed, though.
But what if the request takes 350ms, we are back to the same problem. The
solution here is no longer available because the SUSPENSE_CONFIG
object is not
used anymore, I would have to research or test. Maybe react takes care of this
case under the hood now, hence not SUSPENSE_CONFIG
needed as React has the
best defaults.
Remember render can be called more than once (specially in development).
One of the points of React Query is to abstract catching.
Use useRef()
when you want a variable to have something consistent between
renders instead of re-creating it each render.
You can preload images in JS, with the promise way below
function preloadImage(src) {
return new Promise(resolve => {
const img = document.createElement('img')
img.src = src
img.onload = () => resolve(src)
})
}
Or you can preload them in HTML like this:
<link
rel="preload"
href="%PUBLIC_URL%/img/pokemon/fallback-pokemon.jpg"
as="image"
/>
It looks like I'm better off using Kent's abstraction to suspend stuff
(createResource()
), check examples (this exercis, for instance)
If the images URL is easy to guess (follows a pattern) try to use that rather than get the url from an api call and then having to make another call for the image.
With this hook
const [pokemonResource, isPending] = usePokemonResource(pokemonName)
suspense is even more abstracted.
<React.SuspenseList>
is about loading stuff not as soon as you can but in a
certain order that is more predictable so it's not a jarring experience for the
user. It's experimental, didn't make it to React 18 yet (<React.Suspense>
did).
revealOrder
"together", but "forward" and "backwards" didn't, as they need the
<React.Suspense>
s to be direct children of <React.SuspenseList>
, same for
some of the values of tail
.
Remember you can use nested <React.SuspenseList>
!!