New Feature: Automatic Batching · New Feature: Transitions · New Suspense Features ·
useId()
useTransition()
useDeferredValue()
useSyncExternalStore()
Automatic Batching
Transitions
Suspense Features
React DOM Client
const id = useId();
//useId generates a string
//supports an identifierPrefix to prevent collisions in multi-root apps.
const [isPending, startTransition] = useTransition();
const [count, setCount] = useState(0);startTransition(() => {
setCount(count + 1);
})
//making setCount less urgent then other state update
//isPending indicates when a transition is active to show a pending state:
defer re-rendering a non-urgent part. similar to debouncing, but with few advantages over that.
it accepts a value and returns a new copy of the value that will defer to more urgent updates
If the current render is the result of an urgent update, React will return the previous value and then render the new value after the urgent render has been completed.
const deferredValue = useDeferredValue(value);
Note - useDeferredValue only defers
the value that you pass to it. If you want to prevent a child component
from re-rendering during an urgent update, you must also memoize that component with React.
memo or React.useMemo
useSyncExternalStore(recommended for reading and subscribing from external data sources)
useSyncExternalStore is intended to be used by libraries, not application code.
const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot]);
// subscribe: function to register a callback that is called whenever the store changes.
//getSnapshot: function that returns the current value of the store.
//getServerSnapshot: function that returns the snapshot used during server rendering
Automatic Batching-
Updates inside of async actions(promises, setTimeout) were not batched in React by default. With automatic batching, these updates will be batched automatically
Note- Before this only React events were batched With this update — updates inside of timeouts, promises, // native event handlers will be also batched.
// Before: Render twice, once for each state update
setTimeout(() => {
setCount1(c1 => c1 + 1);
setCount2(c2 => c2 + 1);
}, 1000);
// After: only re-render once at the end
setTimeout(() => {
setCount1(c1 => c1 + 1);
setCount2(c2 => c2 + 1);
}, 1000);
Transitions-
distinguish between urgent and non-urgent updates
Urgent updates- typing, clicking, pressing, and so on.
Transition updates transition the UI from one view to another.
useTransition — For Hooks
startTransition- For Class-Based Components
use startTransition API inside your event to inform React which updates are urgent and which are transitions.
Ex- by typing multiple characters in a row, React will throw out the stale rendering work that wasn’t finished and render only the latest update.
import {startTransition} from 'react';
// Urgent:
setInputValue(input);
// Mark any state updates inside as transitions
startTransition(() => {
setSearchedData(data);
});
Suspense Features-
Support for Suspense on the server has been added and expanded its capabilities using concurrent rendering features.
React DOM Client-
Before
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('app'));
After
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<App />);
Note- createRoot() to hydrate a server-rendered container is not supported. Use hydrateRoot() instead.
CreateRoot and hydrateRoot accept a new option called onRecoverableError in case you want to be notified when React recovers from errors during rendering or hydration for logging.
Happy Learning…👏👏👏👏