React - April 28, 2024

My Favorite React 19 Features

5 minute read

It's been two years since we've seen a major release of React but the wait is finally over. Last week, on April 25, the React team officially released the Beta of React 19 which ships some very useful new features.

When reading through the React 19 blog post some features might look familiar to Next.js developers. The reason for this is that Next.js has been using the canary version of React 19 for the app router. This allowed us to use Server Actions before the React team officially released them in React 19. However, there are still some new features that are unique to React 19 that I'm personally highly excited about. In this post, I'll go over three of them.

Intuitive Context Providers

I'm a big fan of the React Context API and always prefer it over state management libraries like Zustand or Redux unless there's a compelling reason to switch (such as performance or scalability concerns). When I first started learning about the Context API I remember being confused about the Provider component created by the createContext function. With React 19 this has been simplified by using the context itself as the provider. This means that we can go from this:

const ThemeContext = createContext('');
 
function App({children}) {
  return (
    <ThemeContext.Provider value="dark">
      {children}
    </ThemeContext.Provider>
  );  
}

To this:

const ThemeContext = createContext('');
 
function App({children}) {
  return (
    <ThemeContext value="dark">
      {children}
    </ThemeContext>
  );  
}

Even though this is a small change, I think it is a big improvement for the DX of React developers since it makes it more intuitive to use the Context API.

No More forwardRef

Another big improvement for the DX of React developers is the removal of the forwardRef function. This function was used to forward refs to a child component but it was always a bit cumbersome to use. With React 19, we can now use the ref prop directly on the component. This means that we can go from this:

import React, { forwardRef } from 'react';
 
const MyButton = forwardRef((props, ref) => (
  <button ref={ref}>
    {props.children}
  </button>
));

To this:

import React from 'react';
 
const MyButton = ({ ref, children }) => (
  <button ref={ref}>
    {children}
  </button>
);

Document Metadata

Last but not least, React 19 introduces a new way of setting meta tags to the document. Before this feature, we had to do all kinds of crazy things using the useEffect hook. Now we can set the title and meta tags directly in the JSX.

import React, { useEffect } from 'react';
 
const Head = ({ title }) => {
    useEffect(() => {
        document.title = title;
 
        const metaDescriptionTag = document.querySelector('meta[name="description"]');
        if (metaDescriptionTag) {
            metaDescriptionTag.setAttribute('content', 'My page description');
        }
    }, [title]);
 
    return null;
};

Becomes:

function App({ title }) {
    return (
        <>
            <title>{title}</title>
            <meta name="description" content="My page description" />
        </>
    );
}

When rendering this component, React will automatically see the <title> and <meta> tags and set the title and meta tags of the document accordingly. This is a big improvement since this enables us to set metadata tags from both client as server components.

Conclusion

The full release notes of React 19 can be found here. Even though the features above are the ones that stood out the most to me, there are many more features that are worth checking out. For example, the new use() API or the React Compiler (that is still in development).