DEV Community

Cover image for 6 New React 19 Features Everyone Must Use
Boika Candy
Boika Candy

Posted on

6 New React 19 Features Everyone Must Use

If you're already comfortable with React and looking to level up, React 19 brings some really smart new features and improvements. In this post we’ll cover six of the most useful ones — each with a “before” (React 18 or earlier) and an “after” (React 19) snippet so you can see how things have changed.

1) Pass ref as a Prop (No More forwardRef)

Previously, forwarding refs in functional components required React.forwardRef and a little boilerplate. React 19 lets you pass ref directly as a normal prop in many cases.

Before (React 18)

import React, { forwardRef } from 'react';

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});

export default function Parent() {
  const inputRef = React.useRef();
  return <MyInput ref={inputRef} placeholder="Type here…" />;
}

Enter fullscreen mode Exit fullscreen mode

After (React 19)

function MyInput({ placeholder, ref }) {
  return <input placeholder={placeholder} ref={ref} />;
}

export default function Parent() {
  const inputRef = React.useRef();
  return <MyInput ref={inputRef} placeholder="Type here…" />;
}

Enter fullscreen mode Exit fullscreen mode

2. New use() API for Resources/Promises

Why it matters: The new use() hook lets you synchronously “read” a promise or resource inside a render. It works nicely with Suspense and server-rendering.

Before (React 18)

function Comments({ promise }) {
  const [comments, setComments] = React.useState(null);

  React.useEffect(() => {
    promise.then(data => setComments(data));
  }, [promise]);

  if (comments === null) {
    return <div>Loading…</div>;
  }

  return comments.map(c => <p key={c.id}>{c.text}</p>);
}

Enter fullscreen mode Exit fullscreen mode

After (React 19)

import { use } from 'react';

function Comments({ commentsPromise }) {
  const comments = use(commentsPromise);
  return comments.map(c => <p key={c.id}>{c.text}</p>);
}

Enter fullscreen mode Exit fullscreen mode

3. Built-in Form Actions + Hooks (useActionState, useFormStatus, useOptimistic)

React 19 introduces better support for form submissions and optimistic UI updates via Actions and hooks that track pending state.

Before (React 18)

function TodoList() {
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(false);

  const handleSubmit = async event => {
    event.preventDefault();
    setLoading(true);
    const form = new FormData(event.target);
    const res = await fetch('/api/add', { method: 'POST', body: form });
    const newItem = await res.json();
    setItems([...items, newItem]);
    setLoading(false);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="item" placeholder="Add todo…" />
      <button type="submit" disabled={loading}>{loading ? "Saving…" : "Add"}</button>
    </form>
  );
}

Enter fullscreen mode Exit fullscreen mode

After (React 19)

"use client";

import { useActionState } from 'react';

async function create(data) {
  // server-side logic
  return await fetch('/api/add', { method: 'POST', body: data }).then(r => r.json());
}

export default function TodoList() {
  const [error, submit, isPending] = useActionState(create);

  return (
    <form action={submit}>
      <input name="item" placeholder="Add todo…" />
      <button type="submit" disabled={isPending}>
        {isPending ? "Saving…" : "Add"}
      </button>
      {error && <p>{error}</p>}
    </form>
  );
}

Enter fullscreen mode Exit fullscreen mode

4. Native Metadata, Stylesheets & Script Support in Components

React 19 allows you to declare metadata stylesheet dependencies and async scripts inside components more declaratively.

Before (react 18)

import React from 'react';
import { Helmet } from 'react-helmet';

function Page() {
  return (
    <>
      <Helmet>
        <title>My Page</title>
        <meta name="description" content="Hello world"/>
        <link rel="stylesheet" href="/styles.css"/>
      </Helmet>
      <div>Content</div>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

After (React 19)

function Page() {
  return (
    <>
      <title>My Page</title>
      <meta name="description" content="Hello world" />
      <link rel="stylesheet" href="/styles.css" />
      <div>Content</div>
    </>
  );
}




Enter fullscreen mode Exit fullscreen mode

5. Improved Custom Element / Web Component Support

Now you can integrate Web Components more smoothly: props turn into properties (not just attributes) and SSR + client behave more consistently.

Before (React 18)

// Using a Web Component inside React – might need workarounds
<MyWebComponent some-prop="value" />

Enter fullscreen mode Exit fullscreen mode

After (React 19)

<MyWebComponent someProp={value} />

Enter fullscreen mode Exit fullscreen mode

Drop a comment below I'd love to hear your thoughts!

Top comments (0)