React Concurrent
+
React Suspense
Omar Jbara
Fullstack developper @ Cap Collectif
What is React Concurrent
No, seriously, what is it?
A mode that change React's rendering techniques
Interruptible Rendering
Without React Concurrent
- Update some state
- React update the VDOM
- React commit changes and perform DOM manipulations
- The browser has to refresh / paint it's layout
All this stuff is blocking. When React renders, it can not interrupt it's work
Interruptible Rendering
With React Concurrent
- Update some state
- Let the browser paint the update
- Update changes in-memory
- When rendering phase is finished, React commits the changes and updates the DOM accordingly
With this approach, React can prioritize updates and avoid stuterrings
Intentional Loading Sequences
- Avoid jarring UX by controlling when a UI is considered in a "good state" for display
- Gives developpers controls on how to orchestrate these loadings sequences
Concurrent mode
(KISS bby)
- Enable working on several state updates concurrently
- React can prioritize some updates and decides which ones are more important than others
And what about Suspense?
Suspense is a mechanism
- Says that a component is not ready to render
No seriously, that's it
Well, I may have lied to you a bit....
What is exactly Suspense?
-
It is a mechanism for data fetching libraries
- It is a way to read any asynchronous data from a component
- It allows developpers to orchestrate loading UIs and have a fine-grained control over them
What is exactly not Suspense?
-
It is not a data fetching implementation
-
It does not couple data fetching to the view layer
Suspense (and Concurrent) are experimentals
You may expect some BCs
Suspense primitives
The Suspense Component
<Suspense fallback={<Loader />}>
<PostList />
</Suspense>
Display a <Loader/> when <PostList/> is fetching data
Suspense primitives
The SuspenseList Component
<SuspenseList revealOrder="forwards" tail="collapsed">
<Suspense fallback={'Loading...'}>
<ProfilePicture id={1} />
</Suspense>
<Suspense fallback={'Loading...'}>
<ProfilePicture id={2} />
</Suspense>
<Suspense fallback={'Loading...'}>
<ProfilePicture id={3} />
</Suspense>
...
</SuspenseList>
Orchestrate loadings of <ProfilePicture/> components so that they appear from top to bottom
Suspense primitives
The useTransition hook
const SUSPENSE_CONFIG = {timeoutMs: 200 };
function App() {
const [resource, setResource] = useState(initialResource);
const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
return (
<>
<button
disabled={isPending}
onClick={() => {
startTransition(() => {
const nextUserId = getNextId(resource.userId);
setResource(fetchProfileData(nextUserId));
});
}}
>
Next
</button>
{isPending ? " Loading..." : null}
<Suspense fallback={<Spinner />}>
<ProfilePage resource={resource} />
</Suspense>
</>
);
}
Allows to tells React that some user-action will transition to a new state that will cause the component to suspend. This can only be done thanks to Concurrent Mode
React Concurrent
- Allows React to interrupt it's render to do more important stuff and getting back to where it was
- Enables new UI/UX mechanics (loading sequences, loading UIs orchestration...)
- Changes how React's internal rendering is done
React Suspense
- Allows to suspend any components that asks asynchronous data
- Allows a more fine-grained control of loading fallbacks on a per-component basis
- Extract cumbersome loading states logic from the component to the parent
Early adopters:
We are not all Facebook
Thanks you
References
- https://reactjs.org/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html
- https://reactjs.org/docs/concurrent-mode-suspense.html
- https://reactjs.org/docs/concurrent-mode-patterns.html
- https://kentcdodds.com/blog/how-to-enable-react-concurrent-mode
- https://codesandbox.io/s/concurrent-react-example-heyy6
- https://github.com/gaearon/suspense-experimental-github-demo
- https://github.com/Liinkiing/react-concurrent-suspense/
- https://github.com/skovy/react-suspense-img
React Concurrent and Suspense
By Omar Jbara
React Concurrent and Suspense
- 828