Skip to content

What's New in React 18?

Finally, we have a new version of React. Officially, React 18 is now ready to use!

What new features were introduced in this version? Let’s find out in detail.

In my opinion, the latest feature that revolutionized the React Ecosystem was React Hooks, introduced in React 16.8 back in 2019. Since then, we have seen many versions being released. But without any major changes, what will happen in React 18? Let’s dig into the details.

New Features

Concurrent React

According to the official website of React, this is the major addition in React 18. With this new feature released, the devs will benefit from being able to prepare multiple versions of your UI at the same time. So, React will delegate to the dev to identify which changes are important to re-render the component.

// React 17, or 18, without concurrent mode.
import ReactDOM from 'react-dom';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
// React 18 with concurrent mode.
import { createRoot } from 'react-dom/client';

createRoot(
  document.getElementById('root')
).render(
  <App />
)

Automatic Batching

With this new exciting feature, React will combine multiple setState() calls into a single re-render to improve performance. Before this, if we had multiple setState() inside of a setTimeout(), React will re-render for every state update which sometimes causes performance issues if we have larger components.

You may already be familiar with this. This feature was available in React 17, but now it comes out-of-the-box.

// React 17
  setTimeout(() => {
    setCount(c => c + 1);
    setFlag(f => !f);
    // The component will be rendered twice.
  }, 1000);

// React 18
  setTimeout(() => {
    setCount(c => c + 1);
    setFlag(f => !f);
    // The component will be rendered only once.
  }, 1000);

Transitions

This new feature lets the dev split the state update into two categories: urgent and low priority.

For some actions, like selecting in a dropdown or updating a input, you want the action to respond immediately, so now we had the possibility to distinguish between an urgent update and a non-urgent one.

Updates wrapped in startTransition are handled as non-urgent, and will be interrupted if more urgent updates like clicks or keypresses come in.

import { startTransition } from 'react';

// Updating state with urgent priority
setInputValue(input);

// Inside startTransition the updates won't be urgent
// and can be interrumpted
startTransition(() => {
  setSearchQuery(input);
});

New Suspense Features

Finally, we will have Suspense in the server. In the apps that are server-rendered, we will have only one Suspense API.

Another cool thing is if we use Suspense in the server, we will start progressively streaming HTML. This enables selective hydration in the client. On paper, it looks awesome, but what does that mean?

If you are waiting for some data on the server, React can stream HTML for the fallback, and let the user see the rest of the page. When the data is ready, the user will able to see the content HTML.

This means that a single slow data source on the server will no longer hold the entire page back.

New Hooks

When we started this post, we mentioned that a few years ago, Hooks were the latest feature release in React. Now, React 18 will bring new Hooks:

  • useId : we can use this new hook to create a new identifier in the server and in the client.
function Checkbox() {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>Do you follow This Dot on Twitter?</label>
      <input id={id} type="checkbox" name="react"/>
    </>
  );
};
  • useTransition: to create a new state update that has lower priority.
function App() {
  const [isPending, startTransition] = useTransition();
  const [count, setCount] = useState(0);

  function handleClick() {
    startTransition(() => {
      setCount(c => c + 1);
    })
  }

  return (
    <div>
      {isPending && <Spinner />}
      <button onClick={handleClick}>{count}</button>
    </div>
  );
}
  • useDeferredValue: to update some deferred values in a controlled way (perfect for inputs, selects, etc).
function Typeahead() {
  const query = useSearchQuery('');
  const deferredQuery = useDeferredValue(query);

  // Memoizing tells React to only re-render when deferredQuery changes,
  // not when query changes.
  const suggestions = useMemo(() =>
    <SearchSuggestions query={deferredQuery} />,
    [deferredQuery]
  );

  return (
    <>
      <SearchInput query={query} />
      <Suspense fallback="Loading results...">
        {suggestions}
      </Suspense>
    </>
  );
}

IE11 not longer supported

IE11 is no longer supported since React 18. If your app needs to continue bringing support to IE11, you will need to stay at React 17.x.

Conclusion

The most recent release from React includes some cool features like Automatic Batching or Concurrent Mode, which should improve the performance of React in the latest release. I'm really excited to see how these new features will perform in a real-life app, but they look more than promising.

As we see, React 18 introduced out-of-the-box improvements, and new features that look incredible. It has cleared the way for new possibilities in React.js app development.

If you want be aware of the upcoming or most recents changes, you can check out React JS Meetups.