Exploring the Innovations in React 19 !

Exploring the Innovations in React 19 !

Tags
React.js
javascript
Tech
Software Development
Web Dev
Published
Author
Hakim maaouia

Introduction

In the newest Canary version of React.js, labeled as version 19, there are a bunch of changes and cool new features. They're aimed to make it easier for developers to build websites and make them run faster. These updates are going to change how web developers work and improve the React ecosystem. Let's take a closer look at what's new in React 19, including new actions, hooks, and the introduction of the React compiler.

How to setup /React Canary

First to try this version, simply run the following .
⚠️
This React version isn't stable yet, so it's better to stick with the stable version for your production applications and wait for the official release. However, you can still try out the React Canary version to see what's coming.
//for npm npm install react@canary react-dom@canary //for yarn yarn add react@canary react-dom@canary

React Compiler

The React compiler stands out as one of the significant changes in this version, fundamentally altering the approach to development. This compiler automatically optimizes and refines code, eliminating the need for traditional memorization techniques like useMemo and useCallback. By easing excessive re-renders, it can accelerate performance by up to twice as fast, enhancing rendering efficiency and resulting in smoother user experiences. This is particularly noticeable in complex data visualization components that frequently re-render. Notably, React developers have confirmed that the new compiler is already in use in production at Instagram. Furthermore, there are plans to release the first open-source version of the compiler

Seo optimization

In terms of SEO optimization, this version of React brings significant enhancements:
  • Document MetaHead: Simplifies adding titles and meta tags to pages with the <DocumentHead> component, enhancing SEO and brand consistency across the site.
  • Asset Loading: React 19 improves asset loading by starting to load pictures and files in the background while users are still on the current page. This reduces waiting time when transitioning to a new page
  • Server Components: Slow initial page loads and SEO woes can be addressed with Server Components, a game-changer for React development. By rendering components directly on the server using Server Components, developers can deliver lightning-fast first impressions and boost search engine ranking. This is particularly beneficial for content-heavy applications or those that require high SEO performance.

Directives: use client and use server

If you are using React as the front-end framework, now you can use React as a full stack framework with these two directives: use client and use server mark the “split points” between the front-end and server-side environments.use client instructs the packaging tool to generate a <script> tag, while use server we can create components that run exclusively on the server This allows us to do things like write database queries right inside our React components! Here's a quick example of a

Server Component:

đź’ˇ
The key thing to understand is this: Server Components never re-render. They run once on the server to generate the UI. The rendered value is sent to the client and locked in place. As far as React is concerned, this output is immutable, and will never change. For example, we can't useState or useEffect
import db from 'imaginary-db'; async function Homepage() { const link = db.connect('localhost', 'root', 'passw0rd'); const data = await db.query(link, 'SELECT * FROM products'); return ( <> <h1>Trending Products</h1> {data.map((item) => ( <article key={item.id}> <h2>{item.title}</h2> <p>{item.description}</p> </article> ))} </> ); } export default Homepage;

Client Component:

In this new “React Server Components” paradigm, all components are assumed to be Server Components by default. We have to “opt in” for Client Components. like this example
'use client'; import React from 'react'; function Counter() { const [count, setCount] = React.useState(0); return ( <button onClick={() => setCount(count + 1)}> Current value: {count} </button> ); } export default Counter;
These directives allow developers to write both client-side and server-side code in the same file.

Actions

Actions are a new way to deal with things like forms on your website. They let you update your page's info when someone fills out a form, all without making it too complicated. It's a big help for keeping things simple.
The action function can be synchronous or asynchronous. When using actions, React manages the lifecycle of data submission for the developer. We can access the current status and response of form operations through the useFormStatus and useFormState hooks.
<form action={handleSubmit}>

useFormState

useFormState is a Hook that allows you to update state based on the result of a form action.
const [state, formAction] = useFormState(fn, initialState, permalink?);
Call useFormState at the top level of your component to create a component state that is updated when a form action is invoked. You pass useFormState an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state. The latest form state is also passed to the function that you provided. here is an example for better understanding.
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] = useFormState(addToCart, null); return ( <form action={formAction} > <h2>{itemTitle}</h2> <input type='hidden' name='itemID' value={itemID} /> <button type='submit' > Add to Cart </button> <div>{message}</div> </form> ); }; export default AddToCartForm;

useFormStatus

useFormStatus is a hook that provides you with status information regarding the last form submission. Here is an example:
const { pending, data, method, action } = useFormStatus();
import { useFormStatus } from "react-dom"; import action from './actions'; function Submit() { const status = useFormStatus(); return <button disabled={status.pending}>Submit</button> } export default function App() { return ( <form action={action}> <Submit /> </form> ); }

use hook

Call use in your component to read the value of a resource like a Promise or context.
One of the major features of this hook is that it can be called in loops or conditions. On the other hand, it can only be used in a Component or another Hook, as with its predecessors.

use(Promise)

This use hook is designed for handling Promises. When a component utilizes this hook, it will be suspended until the Promise provided to the use hook resolves.
If the component calling use is wrapped in a Suspense block, the fallback will be displayed.
Once the Promise is resolved, the fallback will be replaced by rendering the component using the data returned by the use hook.
If the Promise passed to use is rejected, the fallback of the nearest Error Boundary will be displayed.
In practical terms, this enables better management of Promises, facilitating error catching with Error Boundaries, and effectively managing waiting times with Suspense..
 
import { use, Suspense } from 'react'; const fetchData = async () => { const res = await fetch('https://api.chucknorris.io/jokes/random'); return res.json(); }; const JokeItem = () => { const joke = use(fetchData()); return ( <div> <h2>{joke.value}</h2> </div> ); }; const Joke = () => { return ( <Suspense fallback={ <h2>Loading...</h2> } > <ErrorBoundary fallback={ <div>Something went wrong</div>} > <title>Chuck Norris Jokes</title> <meta name='description' content='Chuck Norris jokes' /> <meta name='keywords' content='chuck norris, jokes' /> <JokeItem /> </ErrorBoundary> </Suspense> ); }; export { Joke as UseExample1 };

use(Context)

Here is an example of using use(Context) , which allows us to access the ThemeContext within a conditional statement, eliminating the need to split components. This not only streamlines the code but also contributes to performance gains by selectively skipping re-renders when the context changes.
import { use } from 'react'; function ThemeDivider({ show }) { if (show) { const theme = use(ThemeContext); return <hr className={theme} />; } return null; }

useOptimistic 

The useOptimistic function allows you to optimistically update the UI during asynchronous operations, such as network requests. It accepts the current state and an update function as parameters, returning a copy of the state that may differ during the asynchronous operation. You need to provide a function that takes the current state and the input of the operation and returns the optimistic state to be used while waiting for the operation. Here is an example of how we can use this.
import { useOptimistic } from 'react'; function AppContainer() { const [state, setState] = useState(initialState); // Assume there's an initial state const [optimisticState, addOptimistic] = useOptimistic( state, // updateFn (currentState, optimisticValue) => { // Merge and return: new state, optimistic value return { …currentState, …optimisticValue }; } ); // Assume there's an asynchronous operation, like submitting a form function handleSubmit(data) { // Use optimistic update before the actual data submission addOptimistic({ data: 'optimistic data' }); // Then perform the asynchronous operation fetch('/api/submit', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }) .then(response => response.json()) .then(realData => { // Update the state with actual data setState(prevState => ({ …prevState, data: realData })); }); } return ( // Render UI using optimisticState <div>{optimisticState.data}</div> ); }
so useOptimistic renders the anticipated result during the asynchronous operation, and once the operation is completed and the state is updated, it renders the actual result, whether successful or not.

Conclusion

React has a grand vision. They aim to blur the lines between the front-end and back-end while maintaining their advantage in client-side capabilities and serving as a gateway to a more performant environment via the React compiler, significantly improving data fetching, form handling, and more.
React 19 is coming soon, possibly in March or April, and it's expected to be another big step forward after the introduction of hooks. Let's wait and see what happens!
 
Â