GAZAR

Principal Engineer | Mentor

Unveiling React 19: A Sneak Peek into Beta Features

Unveiling React 19: A Sneak Peek into Beta Features

If you've been keeping up with the latest in the React world, you're in for a treat. We've got some exciting news to share about the upcoming React 19 release, and trust us, it's going to change the game for developers everywhere.

React Compiler

Ever found yourself knee-deep in code, manually optimizing re-renders with useMemo(), useCallback(), and memo APIs? Well, fret no more! The React team heard your cries and decided to take matters into their own hands with the all-new React Compiler. Say goodbye to manual optimizations—React will now handle re-renders automatically, giving you more time to focus on building awesome stuff.

// Before React 19
const MyComponent = () => {
  const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  return <div>{memoizedValue}</div>;
};

So now:

// After React 19
const MyComponent = () => {
  const memoizedValue = computeExpensiveValue(a, b); // No need for useMemo()
  return <div>{memoizedValue}</div>;
};

https://www.youtube.com/watch?v=kjOacmVsLSE

Remember the useMemo() hook? Well, you can kiss it goodbye in React 19. With the React Compiler doing all the heavy lifting, memoization is now built right into the framework—no hooks required.

Ref handling just got a whole lot simpler with React 19. Say goodbye to forwardRef() and hello to passing refs as props. Less boilerplate, more simplicity—that's what we like to see.

Actions

Say hello to Actions—a nifty little feature that lets you execute both synchronous and asynchronous operations with ease. Whether you're working with forms or managing state updates, Actions have got you covered. And with React 19, we're introducing useOptimistic for managing optimistic updates, making your async workflows smoother than ever.

import { useActionState } from 'react';
import { updateName } from './api';

function ChangeName({ name, setName }) {
  const [error, submitAction, isPending] = useActionState(
    async (previousState, formData) => {
      const error = await updateName(formData.get("name"));
      if (error) {
        return error;
      }
      redirect("/path");
    }
  );

  return (
    <form action={submitAction}>
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </form>
  );
}

Metadata

SEO and accessibility just got a whole lot easier with React 19's Metadata feature. No more juggling title tags and meta descriptions across different routes. Simply drop your metadata right where it belongs—in your React components—and let React handle the rest.

const HomePage = () => {
  return (
    <>
      <title>Freecodecamp</title>
      <meta name="description" content="Freecode camp blogs" />
    </>
  );
}

use() hook

Get ready to simplify your async code with the new use() hook. Promises, async functions, context—this hook does it all, making your code cleaner and more intuitive than ever before.

import { use } from "react";

const fetchUsers = async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/users');
    return res.json();
  };
  const UsersItems = () => {
    const users = use(fetchUsers());
  
    return (
      <ul>
        {users.map((user) => (
          <div key={user.id} className='bg-blue-50 shadow-md p-4 my-6 rounded-lg'>
            <h2 className='text-xl font-bold'>{user.name}</h2>
            <p>{user.email}</p>
          </div>
        ))}
      </ul>
    );
  }; 
export default UsersItems;

useFormStatus() hook

Tired of guessing whether your form submissions are pending or not? Say no more! The useFormStatus() hook in React 19 gives you all the status information you need, right at your fingertips.

const { pending, data, method, action } = useFormStatus();
import { useFormStatus } from "react-dom";

function Submit() {
  const status = useFormStatus();
  return <button disabled={status.pending}>{status.pending ? 'Submitting...' : 'Submit'}</button>;
}

const formAction = async () => {
  // Simulate a delay of 2 seconds
  await new Promise((resolve) => setTimeout(resolve, 3000));
}

const FormStatus = () => {
  return (
    <form action={formAction}>
      <Submit />
    </form>
  );
};

export default FormStatus;

useOptimistic

Last but not least, we've got useOptimistic—a handy little hook that lets you show a different state while async actions are underway. It's like magic, but for your app's UI.

const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true,
      },
    ]
  );

const submitData = async (userData) => {
    addOptimisticMessage(userData.get("username"));

    await sendFormData(userData);
  };

As of now, all the features mentioned above are available in the canary release. You can learn more here. As suggested by the React team,