What's new in React 18

Automatic batching

If two setState hooks are called inside a function, they are batched together and only perform one re-render. However, if we were to use these same hooks inside any other context, like a [[Promise]], an event listener or a setTimeout you would get two renders. It was possible to get the same behavior using unstable_batchedUpdates, but as of [[React]] 18 it's now turned on by default.
const handleClick = () => {
setCount(count + 1)
setClicked(true)
}
const [count, setCount] = React.useState(0)
const [clicked, setClicked] = React.useState(false)

// These calls are batched together and only perform
// on re-render. This works before React 18
const handleClick = () => {
setCount(count + 1)
setClicked(true)
}

// Before React 18, all three of the following cases would perform
// two re-renders.
fetch('...').then(() => {
setCount(count + 1)
setClicked(true)
})

element.addEventlistener('click', () => {
setCount(count + 1)
setClicked(true)
})

setTimeout(() => {
setCount(count + 1)
setClicked(true)
}, 1000)

// If you really want the updates to not be batched you can use
// the flushSync utility from react-dom
import { flushSync } from 'react-dom'

const handleClick = () => {
flushSync(() => {
setCount(count + 1)
})

flushSync(() => {
setClicked(true)
})
}

Transitions

Transitions tell [[React]] which updates are urgent and which are not. A good example would be an input field that filters out a list. Entering an input would be marked as urgent and the filtering of the list is secondary. If the list is in the process of filtering, typing in the input would interrupt the filtering and discard the result.
import { startTransition } from 'react'

// Urgent: Show what was typed
setInputValue(value)

startTransition(() => {
// Secondary: Show results
setSearchQuery(value)
})

Suspense and SSR

[[React]] 18 supports two features for better [[SSR]]: streaming HTML and selective hydration. Streaming HTML means that you can send some pieces of you UI directly and have it wait for other parts that might take longer to load. This works by using the <Suspense> component.
// We render the important parts straight away
<Navigation />
<Article />
// The comments can take longer to load and aren't as important as the
// article. Therefore, we can make the UI wait for this
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
Hydration is the final part of making you page interactive when using SSR. It happens after the [[JavaScript]] has been fetched and loaded. Previously, this part would block the pattern above, but with selective hydration each part can start hydrating whenever that part is ready. If the user starts interacting with a component before it's been fully hydrated, React will prioritize hydrating that component.

ID: 210621072907
Linked references
2021-06-21