React 19 tutorials

9 min readJan 17, 2025
Photo by Alex Knight on Unsplash

In this post we will learn about the new features in React 19, which is officially released few days back.

This post has been inspired by this awesome YouTube video by Traversy Media. And also this YouTube video by RoadsideCoder.

For all the vite fans, it’s better to use create-react-app as it’s coming with React 19. Vite is still shipping React 18, and we need to some hacks to make it React 19.

After creating the app open the package.json which clearly shows React 19.

We will use Tailwind CSS in our project. So, need to give the below commands.

After this as per the documentation, we also need to add the below content in the newly created tailwind.config.js file.

We will also remove all of the styles from index.css and add the below code.

Now, in the App.js we will add some tailwind css styles.

Now, go to http://localhost:3000/ in browser and we will see tailwind css in action.

For checking the updates in React 19, first we will see the pain with React 18. We have created a file JokeUseEffect.js and added the below code in it.

In this we are hitting a popular API to get a random joke. Here, we are using the usual React way of useEffect with empty array. We are using fetch API to get the data. And then setting the data to joke state.

And also setting state loading to false. Inside the return, we are showing a Loading test if loading state is ture. Or else will show the value of joke.

Now, rendering the JokeUseEffect from App.js file.

Now, in http://localhost:3000/ we will see Loading… for 1–2 sec and then will see the data renturned by the API.

Now, we have created a file JokeUse.js inside the components folder. Here, we are using the new use hook from React 19. According to the official defination, it lets us read the values of Promises or Context.

Here, we have a jokePromise variable in which we are using fetch and the then is getting the res.json(). We have also wrapped oyr return in JokeUse with the Suspense which have a fallback of Loading.

We have a new component called JokeItem, which have a variable joke. It uses the use hook to call the jokePromise. After that it returns the html with joke value.

Now, we are rendering the JokeUse from App.js file.

Now, in http://localhost:3000/ the API is hit as earlier.

Now, we will also use the use hook to show result from the jsonplaceholder posts API. Here, we get an array of object but the code is similar to the Joke API code. The only difference is that we are mapping through the posts array and displaying title and body of each post.

We have created a Posts.js file for the same.

Now, we are rendering the Posts from App.js file.

Now, in http://localhost:3000/ we will get the list of posts.

Now, we will see the changes in the useContext API. We have created a Theme.js file. Here, we have the usual code of creating a ThemeCOntext with createContext().

We are simply toggling the theme between light and dark. Also, in the return statement we are using the provider and passing the value of theme and toggleTheme and the children props.

In the same file, we have a ThemeCard component, which is using the useContext hook to take the ThemeContext. And extacting the theme and toggleTheme.

In the return statement we are changing the theme of everything according to the theme. And we also have a button to toggle the theme. The final component called Theme is using the ThemeProvider component and passing ThemeCard as children.

Now, we are rendering the Theme component from App.js file. In http://localhost:3000/ we call switch between themes by switching the button.

Now, the changes which are done in React 19 is that the useContext hook is replaced by the use hook. And we did the same in Theme.js file.

In http://localhost:3000/ we ar still able to switch between themes.

Now, we will see the changes in Form which traditionally uses a lot of code. So, we have created a PostForm.js file. Here, we have a PostItem component, which is taking post props and displaying the title and body.

After this we have a Form component and it is taking an addPost props. We are using the state of title and body. The handleSubmit function which runs on clicking the Submit button, create a newPost from title and body. After that it is using addPost and passing the newPost.

In the return we have the usual React 18 type of controlled component, where value and onChange is there for title and body.

The final part of the PostForm.js file contains the PostForm component. Here, we have a posts state and a addPost function. It uses the prevPosts and add newPost to it.

The return statement renders the Form component and passes addPost as props. Also, we are mapping through posts and passing each post to the PostItem component.

Now, in http://localhost:3000/ we are able to give a title and body and add items.

Now, instead of value and onChange in all input fields we will use the name. Also, instead of onSumbit, now we have action in React 19, which is calling a function formAction.

Notice that we have also removed state and handleSubmit function. The formAction gets a special props called formData. And we can get the fields with formData.get().

We are storing this in title and body respectively and creating the newPost object. We are passing this to the addPost().

We have created a new file called PostFormActions.js and made this changes.

Our form is still working like earlier in http://localhost:3000/

Now, we will look into the concept of useFormStatus. For this we have created a new file called PostFormStatus.js which is similar to our earlier file PostFormActions.js.

But here the button logic we have shifted to a component called SubmitButton.

Now, we are importing a new hook called useFormStatus from react-dom. Also, we have created the SubmitButton component, which is using pending from useFormStatus. The return statement have the same button as earlier.

But it is disabled if pending is true. Also, if pending is true we will see the Submitting text or else Submit text. We have also added a delay in the formAction, so that we can see the transition from Submitting to Submit.

Now, in http://localhost:3000/ we write a title and body and click on the Submit button, it will show Submitting… for 2 seconds and then the details will be added.

Next, we will learn about useOptimistic hook. As per the defination, it lets you show different state while async action is going on. We have created a TodoList.js file and added the usual todo code.

Here, we have used the formData which we have learnt earlier. But we have a state of todos and updating it with setTodos.

In http://localhost:3000/ the list is getting added properly but the pending is not shown and we need to add additional code for it.

We are going to use the pending by using useOptimistic hook. Here, we have defined an optimistics state, which can be changed with setOptimistics. The syntax is quite similar to useState hook.

Inside the useOptimistic, we are taking the todos state as first parameter. The second parameter is a function which takes oldTodos and newTodo. Inside the function the oldTodos is spreaded and added text as newTodo and made pending to true.

Inside the handleAddTodo we are using setOptimistics and passing the newTodo. Inside the return statement, instead of todos we are passing the optimistics array.

Now, in http://localhost:3000/ after adding an item and clicking SUbmit button we will see the (Adding…) for 2 seconds.

Now, we will look into the changes in forwardRefs changes. For this we will create a new file called RefContainer.js and add the below code in it.

Here, we have the a inputRef and that is passed as a ref to a CustomInput component. The button onClick will call handleFocus function which will focus the input.

Next, we will create the CustomInput.js file where we need forwardRef to get the ref. Here, we are using the ref in a input.

Now, the http://localhost:3000/ when we will click on the Focus button we will get the click on the input.

Now, the changes in React 19 is that instead of forwardRef we can use the ref as a normal prop, as in the code below.

Our focus still works the same in http://localhost:3000/

This completes our React 19 demo. You can find the code for the same here.

--

--

Nabendu Biswas
Nabendu Biswas

Written by Nabendu Biswas

Architect, ReactJS & Ecosystem Expert, Youtuber, Blogger

No responses yet