React is one of the most popular and easy-to-use JavaScript frontend frameworks that helps you build captivating user interfaces for modern web applications. Its component-based architecture allows for reusable and efficient UI development, making it a go-to choice for front-end web development.
React 19 is an experimental version of the React library, inspired by features implemented in the Instagram app. The React community is actively working on upcoming features and hooks that primarily focus on two major areas in React: data fetching and forms. These hooks are designed to enhance the productivity of all React developers, particularly those working on single-page applications (SPAs).
React Hooks have been a game-changer since their introduction in React 16.8. In React 19, the way we use useMemo, forwardRef, useEffect, and useContext will change. A new hook, use, will be introduced, simplifying the handling of promises, async/await, and context.
React already has a compiler for converting React code into vanilla JavaScript. In React 19, the compiler will automatically memoize values, functions, and components, reducing the need for manual optimization hooks like useMemo, useCallback, and the memo API.
React 19 will provide automatic memoization, eliminating the need to manually optimize re-renders using built-in hooks like useMemo, useCallback, and the memo API.
React 19 will introduce server components, allowing components to run on the server-side. This feature brings numerous advantages, including improved SEO, performance boosts, and seamless server-side execution of code and API calls.
Web components allow you to create custom components using native HTML, CSS, and JavaScript. React 19 will make it easier to integrate web components into your React code without the need for conversion or additional packages.
React 19 will enable developers to manage document metadata, such as titles, meta tags, and descriptions, directly within their React components, improving SEO and accessibility for single-page applications.
React 19 will likely introduce improvements for asset loading, making it easier to manage and optimize the loading of assets like images, fonts, and other resources in your React applications.
While React 19 is still in an experimental stage, the React community is actively working on these exciting new features and hooks. As the release approaches, developers can look forward to building more efficient, optimized, and accessible web applications using the latest advancements in the React ecosystem.
Stay tuned for updates and announcements regarding the official release of React 19 and keep checking the official website and get ready to harness the power of these new features and hooks for your modern frontend web development projects. Below you will find samples of how the code will look different with React 19
React Hooks have been one of the most loved features introduced in the library. You have likely used React's built-in hooks many times, and perhaps you've tried making your own custom hooks, too. Hooks are so popular that they've become a React programming pattern.
In React 19, the way we use useMemo, forwardRef, useEffect, and useContext will change. This is mainly because a new hook, use, will be introduced
In React 19, we do not need handle unnecessary re-rendering the development compiler will be memoizing by itself
Before:
const items = new Array(20_000).fill(0)?.map((_, i) => {
return {
id: i,
isSelected: i === 19_9999,
};
});
import React, { useMemo, useState } from "React";
export const MemoHook = () => {
const [count, setCount] = useState(0);
const [records, setRecords] = useState(items);
const selectedItem = useMemo(
() => records.find((item) => item.isSelected),
[items]
);
return (
<div>
<h1>Count : {count}</h1>
<h2> Selected Item : {selectedItem?.id}</h2>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
const items = new Array(20_000).fill(0)?.map((_, i) => {
return {
id: i,
isSelected: i === 19_9999,
};
});
import React, { useState } from "React";
export const MemoHook = () => {
const [count, setCount] = useState(0);
const [records, setRecords] = useState(items);
let selectedItem = records?.find((item) => item.isSelected); //compiler will memoized by itself
return (
<div>
<h1>Count : {count}</h1>
<h2> Selected Item : {selectedItem?.id}</h2>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
ref will be now passed as props rather than using the forwardRef() hook. This will simplify the code. So after React19, you won't need to use forwardRef()
import React, { forwardRef } from 'react';
const ExampleButton = forwardRef((props, ref) => (
<button ref={ref}>
{props.children}
</button>
));
import React from 'React';
const ExampleButton = ({ ref, children }) => (
<button ref={ref}>
{children}
</button>
);
In React 19, community will introduce the use() hook, this hook will help to handle the promises, async await and context, we don't need to use useContext hook
syntax : const resource = use(promiseResource) or use(contextResource)
import { useEffect, useState } from "react";
const TodoItem = ({ todo }) => {
return (
<div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg">
<h2 className="text-xl font-bold">{todo.title}</h2>
<h4 className="text-xl font-bold">{todo.description}</h4>
</div>
);
};
const Todos = () => {
const [todos, setTodos] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchTodos = async () => {
try {
const res = await fetch("http://localhost:3001/todo");
const data = await res.json();
setTodos(data);
setLoading(false);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
fetchTodos();
}, []);
if (loading) {
return <h2 className="text-2xl text-center font-bold mt-5">Loading...</h2>;
}
return (
<>
{todos?.map((todo) => (
<TodoItem todo={todo} />
))}
</>
);
};
export default Todos;
import { use, Suspense } from "react";
const fetchTodo = async () => {
const res = await fetch("http://localhost:3001/todo");
return res.json(); // there is no need to define await use hook will automatically handle promises
};
const TodoItem = () => {
const todos = use(fetchTodo()); //use will handle promise by itself we wont need to use async await and then catch block
return (
<>
{todos?.map((todo) => (
<div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg">
<h2 className="text-xl font-bold">{todo.title}</h2>
</div>
))}
</>
);
};
//Concise the code
const Todo = () => {
return (
<Suspense
fallback={
<h2 className="text-2xl text-center font-bold mt-5">Loading...</h2>
}
>
<TodoItem />
</Suspense>
);
};
export default todos;
import React, { createContext, useState, useContext } from 'react';
// Create a context object
const ThemeContext = createContext();
// Create a provider component
const ThemeProvider = ({ children }) => {
// State to hold the current theme
const [theme, setTheme] = useState('light');
// Function to toggle theme
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
// Provide the theme and toggleTheme function to the children
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
const ThemedButton = () => {
// Access the theme context using the useContext hook
const { theme, toggleTheme } = use(ThemeContext); // We wont need to useContext to access the context
return (
<button
onClick={toggleTheme}
className='px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-md focus:outline-none focus:ring-2 focus:ring-blue-600'
>
{theme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'}
</button>
);
};
const Theme = () => {
return (
<ThemeProvider>
<ThemedButton />
</ThemeProvider>
);
};
export default Theme;
This new use hook has a hidden power: Unlike all other React Hooks, use can be called within loops and conditional statements like if.
Form Action: This new feature enables you to pass a function to the action prop of a <form>. React will call this function when the form is submitted
syntax : <form action={handleSubmit} />
Remember that if you add a <form action> prop in React 18, you get this warning Warning: Invalid value for prop action on <form> tag. Either remove it from the element or pass a string or number value to keep it in the DOM.
useActionState: useActionState is a Hook that allows you to update state based on the result of a form action
syntax : const [state, formAction] = useActionState(fn, initialState, permalink?);
Example:
import { useFormState } from 'react-dom';
const addToCart = (prevState, queryData) => {
const itemID = queryData.get('itemID');
if (itemID === '1') {
return 'Added to cart';
} else {
return "Couldn't add to cart: the item is sold out.";
}
};
const AddToCartForm = ({ itemID, itemTitle }) => {
const [message, formAction] = useActionState(addToCart, null);
return (
<form
action={formAction}
className='bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4'
>
<h2 className='text-xl font-bold mb-4'>{itemTitle}</h2>
<input type='hidden' name='itemID' value={itemID} />
<button
type='submit'
className='bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline'
>
Add to Cart
</button>
<div className='mt-4 text-sm text-gray-700'>{message}</div>
</form>
);
};
export default AddToCartForm;
lets you know if a parent <form> is currently submitting or has submitted successfully. It can be called from children of the form, and it returns an object with the following properties
syntax : const { pending, data, method, action } = useFormStatus();
Let's see what's going on here:
pending: if the form is in a pending state, then it will be true, otherwise it will be false.
data: an object implementing the FormData interface that contains the data and the parent <form> is submitting.
method: the HTTP method – GET, or POST. By default it will be GET.
action: a function reference.
import { useFormStatus } from "react-dom";
import { useState } from "react";
// PostItem component
const BlogItem = ({ blog }) => {
return (
<div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg">
<h2 className="text-xl font-bold">{blog.title}</h2>
<p>{blog.description}</p>
</div>
);
};
const Blogs = () => {
const { pending } = useFormStatus();
const [blogs, setBlogs] = useState([]);
const addNewBlog = (newBlog) => {
setBlogs((blogs) => [...blogs, newBlog]);
};
const formAction = async (formData) => {
// Simulate a delay of 2 seconds
await new Promise((resolve) => setTimeout(resolve, 2000));
// We have direct access to the form data
const newPost = {
title: formData.get("title"),
body: formData.get("body"),
};
addNewBlog(newPost);
};
return (
<>
<form
action={formAction}
className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
>
<input
type="text"
name="title"
id="title"
placeholder="Enter the title of the blog"
/>
<input
type="description"
name="description"
id="description"
placeholder="Enter the description of the blog"
/>
<div className="flex items-center justify-between">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
type="submit"
disabled={pending}
>
{pending ? "Submitting..." : "Submit"}
</button>
</div>
</form>
{blogs.map((blog, index) => (
<BlogItem key={index} blog={blog} />
))}
</>
);
};
export default Blogs;
Note: forms hooks must be imported from React-dom, not React
**useOptimistic() : **The useOptimistic hook will immediately update the UI assuming the request will succeed. The name is "optimistic" because the user will see the optimistic (success) result of performing an action, even though the action actually takes time to complete
import { useOptimistic, useState, useRef } from 'react';
const MessageForm = ({ addOptimisticMessage, sendMessage }) => {
// Create a reference to the form
const formRef = useRef();
// This function is called when the form is submitted
const formAction = async (formData) => {
addOptimisticMessage(formData.get('message'));
// Clear the form
formRef.current.reset();
await sendMessage(formData);
};
return (
<form action={formAction} ref={formRef} className='flex items-center mb-5'>
<input
type='text'
name='message'
placeholder='Hello!'
className='border border-gray-300 rounded py-1 px-2 mr-2 focus:outline-none focus:border-blue-500'
/>
<button
type='submit'
className='bg-blue-500 hover:bg-blue-600 text-white font-semibold py-1 px-4 rounded focus:outline-none focus:shadow-outline'
>
Send
</button>
</form>
);
};
const Thread = ({ messages, sendMessage }) => {
// The useOptimistic hook is used to add an optimistic message to the list of messages
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
(state, newMessage) => [
...state,
{
text: newMessage,
sending: true,
},
]
);
return (
<div>
<MessageForm
addOptimisticMessage={addOptimisticMessage}
sendMessage={sendMessage}
/>
{optimisticMessages.map((message, index) => (
<div key={index} className='flex items-center'>
<span>{message.text}</span>
{message.sending && (
<small className='ml-1 text-gray-500'>(Sending...)</small>
)}
</div>
))}
</div>
);
};
const deliverMessage = async (message) => {
// Simulate a delay
await new Promise((res) => setTimeout(res, 1000));
return message;
};
const MessageBox = () => {
const [messages, setMessages] = useState([]);
async function sendMessage(formData) {
const sentMessage = await deliverMessage(formData.get('message'));
setMessages((messages) => [...messages, { text: sentMessage }]);
}
return <Thread messages={messages} sendMessage={sendMessage} />;
};
export default MessageForm;
React Compiler : React has already a compiler for converting the React code into vanilla javascript what is the new in React compiler in React 19 then It should be automatically memoized the value, function and component
Optimizations -- Currently, React doesn't automatically re-render during the state change. A way to optimise these re-renders is to manually use some hook according to the variables, let say If I memoized the value then we used useMemo() and If I memoized the function then we use useCallback() and for the whole component then we use memo API. As per React's team, this was a "reasonable manual compromise". Their vision was to let React manage these re-renders
In React 19 wil provide use automatically memoization then we no need to use these built-In hooks like useMemo(), useCallback() and memo APIs
Server Components -- React components have primarily focused on run on the client side. But React is introducing the groundbreaking concept of running components on the server side, If you want to know about server components then you should go through the Next.js documentation. Nextjs is React framework.
In React 19, server components will be integrated directly into React, bringing a host of advantages:
SEO: Server-rendered components enhance search engine optimisation by providing more accessible content to web crawlers.
**Performance Boost: **Server components contribute to faster initial page loads and improved overall performance, particularly for content-heavy applications.
Server-Side Execution: Server components enable executing code on the server, making tasks like API calls seamless and efficient.
By default, all components in React are client-side. Only when using ‘use server’ will the component become a server component.
'use server';
export default async function requestUserInfo(formData) {
const username = formData.get('username');
if (canRequest(username)) {
return 'successful';
}
return 'failed';
}
In React 19, you will be using the server component as NextJs
Web components - Web components allow you to create custom components using native HTML, CSS, and JavaScript, seamlessly incorporating them into your web applications as if they were standard HTML tags
Currently, integrating web components into React isn't straightforward. Typically, you either need to convert the web component to a React component or install extra packages and write additional code to make web components work with React. This can be frustrating.
Luckily, React 19 will help you integrate web components into your React code much more easily. If you come across a really useful web component, such as a carousel, you can seamlessly incorporate it into your React projects without the need to convert it into React code
Document MetaData: Elements like "title," "meta tags," and "description" are crucial in optimising SEO and ensuring accessibility. In React, where single-page applications are prevalent, managing these elements across different routes can be a bit of a hassle
we define all meta tags and title inside the index.html and React is single page application then we define all the tags and SEO related script in index.html
In React 19, we can use the title and meta tags directly in our React components like that
const Component = () => {
return (
<>
<title>React 19</title>
<meta name="React" content="React 19 hooks anf features" />
// Page content
</>
);
}