Frontend Development 17 min read

React 19 New Features: use API, Preload API, Actions, Optimistic Updates, and React Compiler

This article introduces the new React 19 APIs—including the versatile use API for data fetching and conditional context, resource preloading helpers, enhanced Actions with useTransition, useActionState, useFormState, useOptimistic, as well as deprecations, improved hydrate error messages, and the experimental React Compiler—providing code examples and migration guidance.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
React 19 New Features: use API, Preload API, Actions, Optimistic Updates, and React Compiler

As of today the React team has published a Release Candidate for version 19.0.0 on NPM, bringing several previously unseen features and simplifying or removing many criticized APIs.

New use API

React 19 introduces a multipurpose use API with two main uses: fetching data during component render and conditionally reading a context.

Asynchronous data fetching

The use API accepts a Promise and suspends rendering until the promise is fulfilled, typically used together with Suspense . Previously this required a combination of useState , useEffect , and manual state updates.

import { useState, useEffect } from 'react';
import './App.css';

function getPerson(): Promise<{ name: string }> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ name: '19Qingfeng' });
    }, 1000);
  });
}

const personPromise = getPerson();

function App() {
  const [loading, setLoading] = useState(false);
  const [name, setName] = useState
();

  useEffect(() => {
    setLoading(true);
    personPromise.then(({ name }) => {
      setName(name);
      setLoading(false);
    });
  }, []);

  return (
Hello:
{loading ? 'loading' :
userName: {name}
}
);
}

export default App;

With the new use API the same logic becomes much shorter:

import { use, Suspense } from 'react';
import './App.css';

function getPerson(): Promise<{ name: string }> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ name: '19Qingfeng' });
    }, 1000);
  });
}

const personPromise = getPerson();

function Person() {
  const person = use(personPromise);
  return
userName: {person.name}
;
}

function App() {
  return (
Hello:
Loading...
}>
);
}

export default App;

Conditional Context reading

Before React 19, useContext had to be called unconditionally at the top of a component. The new use API allows conditional context access while still respecting the rule that hooks must be called inside the render function.

import { use } from 'react';
import ThemeContext from './ThemeContext';

function Heading({ children }) {
  if (children == null) {
    return null;
  }
  const theme = use(ThemeContext);
  return
{children}
;
}

Resource Preloading API

React 19 adds helpers such as prefetchDNS , preconnect , preload , and preinit to hint the browser about resources that should be fetched early, improving page performance.

import { prefetchDNS, preconnect, preload, preinit } from 'react-dom';
function MyComponent() {
  preinit('https://.../path/to/some/script.js', { as: 'script' });
  preload('https://.../path/to/font.woff', { as: 'font' });
  preload('https://.../path/to/stylesheet.css', { as: 'style' });
  prefetchDNS('https://...');
  preconnect('https://...');
}

Actions and useTransition

Actions simplify async form handling. With useTransition , the pending state is managed automatically.

import { useState, useTransition } from 'react';

function updateName(name) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(undefined), 1000);
  });
}

export default function UpdateName() {
  const [name, setName] = useState('');
  const [error, setError] = useState(null);
  const [isPending, startTransition] = useTransition();

  const handleSubmit = () => {
    startTransition(async () => {
      const error = await updateName(name);
      if (error) {
        setError(error);
        return;
      }
      console.log('Form submitted');
    });
  };

  return (
setName(e.target.value)} />
Update
{error &&
{error}
}
);
}

useActionState

useActionState returns a wrapped action function, its state, and a pending flag, allowing concise form submission handling.

import { useActionState } from 'react';

let index = 0;
function updateName(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      index++ === 0 ? resolve('Form updated') : reject();
    }, 200);
  });
}

export default function ChangeName() {
  const [state, submitAction, isPending] = useActionState(
    async (prev, formData) => {
      try {
        const result = await updateName(formData.get('name'));
        return result;
      } catch (e) {
        return e;
      }
    },
    null
  );
  return (
Update
{state}
);
}

useFormStatus (formerly useFormState )

This hook provides the pending state and other form metadata directly inside form children.

import { useFormStatus } from 'react-dom';
function DesignButton() {
  const { pending } = useFormStatus();
  return
;
}

useOptimistic

Optimistic updates let the UI reflect changes immediately while the server request is in flight, rolling back on failure.

// Thread.tsx
import { useOptimistic, useRef } from 'react';

export async function deliverMessage(message) {
  await new Promise((res) => setTimeout(res, 1000));
  return message;
}

export function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get('message'));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [...state, { text: newMessage, sending: true }]
  );
  return (
    <>
      {optimisticMessages.map((msg, i) => (
{msg.text}{msg.sending &&
(Sending...)
}
))}
Send
);
}

// main.tsx
import { Thread, deliverMessage } from './actions/happy.tsx';
import './index.css';
function App() {
  const [messages, setMessages] = useState([
    { text: 'Hello there!', sending: false, key: 1 }
  ]);
  async function sendMessage(formData) {
    try {
      const sentMessage = await deliverMessage(formData.get('message'));
      setMessages((msgs) => [...msgs, { text: sentMessage }]);
    } catch (e) {
      console.error(e);
    }
  }
  return
;
}

ReactDOM.createRoot(document.getElementById('root')!).render(
);

Other Improvements

forwardRef deprecation: In React 19 the forwardRef API is slated for removal; refs can be passed as regular props in function components (but not in class components).

Better hydrate error messages: Server‑side rendering now reports a single concise mismatch message to aid debugging.

Direct Context rendering: A <Context> element can now act as a provider without the explicit <Context.Provider> wrapper.

Cleanable refs: Ref callbacks may return a cleanup function that runs when the element is removed from the DOM.

React Compiler (experimental)

The React Compiler automatically memoizes component code at compile time, reducing the need for manual useMemo or useCallback usage. While still experimental, it can significantly improve performance by generating optimized render functions.

// before
const Component = () => {
  const onSubmit = () => {};
  const onMount = () => {};
  useEffect(() => {
    onMount();
  }, [onMount]);
  return
;
};

// after (compiler adds memoization)
const FormMemo = React.memo(Form);
const Component = () => {
  const onSubmit = useCallback(() => {}, []);
  const onMount = useCallback(() => {}, []);
  useEffect(() => {
    onMount();
  }, [onMount]);
  return
;
};

For more details, see the official React Compiler documentation.

frontendreactSuspenseReact Compileruse APIuseOptimisticuseTransition
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.