Tips & Tricks Upgrading to React 18

Fortum Tech
Fortum Technology Blog
6 min readNov 15, 2022

This article contains warnings, and errors while upgrading a project to React v18. You may face the same issues and get hints on how to solve those problems.

In this article we are going to update:

In case you don’t know, React is a free and open-source front-end JavaScript library for building single page application (SPA) based on UI components. This latest React version (18) contains an exciting list of features that are worth exploring!

Any react application using prior version of react also uses other libraries depending on the application needs. Applications require routing, state management, location services and other features. These libraries need to be upgraded most of the time to work without any errors.

Upgrade react

The first command to upgrade a project to react v18: yarn add react react-dom

We use typescript. So, the obvious update is to update typescript definitions for both react and react-dom. Otherwise there is a problem already displayed:

Could not find a declaration file for module ‘react-dom/client’

Are you using Typescript in your project? “react-dom” has a type definition. Let’s install that: yarn add –D @types/react @types/react-dom

There is a warning about : ReactDOM.render is no longer supported in React 18

Overcoming issues with the new root API

There is a step by step guide about how to use the new API: use new root API

I did not use:

// createRoot(container!) if you use TypeScript

You may face forbidden non-null assertion issue from Typescript.

Only change I made from the document is this:

const container = document.getElementById('example-root-container'); 

if (container) {

const root = createRoot(container);

root.render(<Main />);

}

Hopefully, you will not face : Type null is not assignable to type Element | DocumentFragment

Adjusting children props

Issue: children props needs to be explicitly listed:

For typescript based react project, there is another issue to resolve: children props needs to be explicitly listed. Otherwise, there is an error thrown from our project. Property ‘children’ does not exist on type ConfirmationModalProps (an example props used with our confirmation modal).

I just added children property in each complaining component as per the react document suggested.children?: React.ReactNode;

Fixing react-redux incorrect peer dependency

After upgrading the project to React 18, there are requirements to upgrade other related libraries. There are warnings already shown up:

Warning: “react-redux@7.x.x” has incorrect peer dependency “react@¹⁶.8.3 || ^17”.

We are using react-redux and react-router-dom in the project. Both modules have incorrect peer dependencies. The current version of react-redux and react-router-dom is not compatible with React 18.

Because of this incompatibility there is a problem with Provider component from “react-redux”;

“‘Provider’ cannot be used as a JSX component.\n Its instance type ‘Provider<AppAction>’ is not a valid JSX element.\n The types returned by ‘render()’ are incompatible between these types.\n “

“react-redux” v8.x.x is React v18 compitable. Let’s update our react-redux following this: npm i react-redux@latest or, yarn add react-redux@latest

At the time of writing this article, react-redux 8.0.2 was available. Voila! Our app is not complaining about react-redux or Provider component any more.

Upgrading react-router-dom to V6

warning “react-router-dom > react-router > mini-create-react-context@0.4.1” has incorrect peer dependency “react@⁰.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0”.

So, I checked what version of react-router-dom is used in the project using:yarn list react-router-dom

The above command produces react-router-dom@5.x.0.

There is already v6 available for react-router-dom. Here comes the update:yarn add react-router-dom

In our project, react-router-dom@6.3.0 was installed.

And for typescript:yarn add –D @types/react-router-dom

No switch, useHistory, Redirect in react-router-dom@v6:

From react-router-dom, there are multiple errors:

TS2305: Module '"react-router-dom"' has no exported member 'Redirect'. 

TS2305: Module '"react-router-dom"' has no exported member 'Switch'.

TS2305: Module '"react-router-dom"' has no exported member 'useHistory'.

Property 'exact' does not exist on type 'IntrinsicAttributes & (PathRouteProps | LayoutRouteProps | IndexRouteProps)'

There is a detailed list of how to upgrade to react-router-dom@v6

  • Switch needs to be converted to Routes
  • There is no exact anymore. There is better provision for relative links
  • UseHistory becomes useNavigate
console.error  
40 Error: Uncaught [Error: useNavigate() may be used only in the context of a <Router> component
  • BrowserRouter should wrap the App / top level component to get rid of the useNavigate() error.

Update redux-thunk!

Here comes another issue with AppThunk. We are using vanilla redux v8.

Error states: “Argument of type AppThunk is not assignable to parameter of type AnyAction” — there is a property type missing in type AppThunk but required in type AnyAction.

The solution is mentioned here: Missing type in AppThunk — issue

I chose: import type {} from ‘redux-thunk/extend-redux’;

I found out that there is a type error from redux-thunk/extend-redux:

Cannot find module ‘redux-thunk/extend-redux’ or its corresponding type declarations.

Redux-thunk/extend-redux is available from version 2.4.1 but our project is using version lower than that.

So, what’s the obvious action here? yarn add redux-thunk

All the AppThunk problems are gone.

Update @testing-library/react:

Are you also using @testing-library/react?

What is the version of @testing-library/react are you using before upgrading to React v18?

In our project it is @testing-library/react@11.x.x yarn list @testing-library/react

According to the testing-library, upgrading to v13.0.0 should resolve the problem of :

console.error 
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

Let’s upgrade @testing-library:yarn add –D @testing-library/react

This installed v13.3.0 of @testing-library/react.

All the console.error about createRoot in testing were gone.

BUT!

Here comes another one:

 console.error 
Warning: A suspended resource finished loading inside a test, but the event was not wrapped in act(...).

This is the page contains all the tricks to solve the issues regarding act() wrapper — https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning

What’s left next for the upgrade to React v18?

About the Author:

Robin Sajjad, Senior Software Engineer at Fortum

Robin Sajjad

--

--