Upgrading a create-react-app game to React 18

Matti Bar-Zeev - Jan 7 '22 - - Dev Community

Join me in this (short) post as I upgrade my Word-Search React game to the new and shiny version of React 18.

The message was loud and clear in the latest React conf:

Image description

So I was like “Nice, seems like a good time to upgrade my Word-Search game to start using it.”, but other interesting things drew my attention, and so here we are now - upgrading to React 18. Let’s go!

My Word-Search game is a project which started (and continued on) as a Create-React-App project and is currently using React 16.9.0 (😱). My mission is to upgrade it to React 18 and with hopes that all remains working. I’m not going to use any of the new features React 18 offers in the course of this upgrade, but just make sure it all stays intact.

As always, I start with the docs, and surely enough they've taken me into another document which explains upgrading to React 18 on the client.
So first things first, the initial step is to actually install the new React version, but what is the new version? The docs say to upgrade to 18, but is it 18.0.0? 18.0.2? Surely not alpha or beta, right?
You know what, let’s try installing the latest version of React:



npm install react@latest react-dom@latest


Enter fullscreen mode Exit fullscreen mode

Well, nope. The latest version is 17.0.2, so what do we do?

I’m heading down to the React Conf recap to find how we should install React 18. Oh, I see it now - I need to install the React RC (Release Candidate) version, which kinda throws me off tracks since in this discussion on the React-18 working group, published on May 2021, it suggests that the final release will be available at around July 2021 (Notice the dates on the image below)

Image description

No worries - let’s install the release candidate -



npm install react@rc react-dom@rc


Enter fullscreen mode Exit fullscreen mode

Yeah, so my package.json now have the new rc versions of react and react-dom:



"react": "^18.0.0-rc.0",
"react-dom": "^18.0.0-rc.0",


Enter fullscreen mode Exit fullscreen mode

Let’s try and fire-up the application and see the sparks -
Funny thing I noticed when running “npm start” on my upgraded create-react-app project. It modifies the root tsconfig.json file “jsx” property and now instead of being:



"jsx": "react"


Enter fullscreen mode Exit fullscreen mode

It is:



"jsx": "react-jsx"


Enter fullscreen mode Exit fullscreen mode

Reading the TS docs I gather that this change was introduced in React 17, and has to do with how TSC transpile JSX in React 17 and above. Good to know.

The game is up! Let’s try and play with it. I’m grabbing a word from the scattered letters, the animation and everything works well. I drop it on the matching word in the words panel to check my answer and... BOOM.
It seems that I have an issue with updating the style of the floating letters -

Image description

😳
Well, I cheated a little, since I did not completed the migration as requested, specifically this part:



// before
const container = document.getElementById('root');
ReactDOM.render(<App />, container);

// after
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<App/>);


Enter fullscreen mode Exit fullscreen mode

Let’s do that and see if it fixes the error I’m getting.
My rendering code used to be like this:



const rootElement = document.getElementById('root');
const render = () => {
   ReactDOM.render(
       <Provider store={gameStore}>
           <App />
       </Provider>,
       rootElement || document.createElement('div')
   );
};


Enter fullscreen mode Exit fullscreen mode

And I modified it to be compatible with React 18, like this:



const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
const render = () => {
   root.render(
       <Provider store={gameStore}>
           <App />
       </Provider>
   );
};


Enter fullscreen mode Exit fullscreen mode

Let’s check if the error I had is gone… It is! Awesome. The game works as expected :)

What about testing?
All test pass but they now have a new warning to them:



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


Enter fullscreen mode Exit fullscreen mode

What React Testing Library suggests is to install the latest alpha version, let’s try that



npm i @testing-library/react@alpha -D


Enter fullscreen mode Exit fullscreen mode

Yep. running the tests now does not have any warnings. I’m not feeling that comfortable with an alpha version, but I can live with this one for now.

And so my Word-Search game is now updated with the RC version of React 18 and all seems to work well. Since the game does not have a BE involved, most of the new features of React 18 are irrelevant, but who knows… they might be relevant in the future ;)
As always, if you have any ideas on how to make this better or any other technique, be sure to share with the rest of us!

Hey! If you liked what you've just read check out @mattibarzeev on Twitter 🍻

Photo by Lindsay Henwood on Unsplash

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .