Upgrading a create-react-app game to React 18
Tags: react, javascript, webdev, gamedev
Published: 2022-01-07 08:20:32

Join me in this (short) post as I upgrade my [Word-Search React game](https://word-search-react-game.netlify.app/) to the new and shiny version of React 18.

The message was loud and clear in the [latest React conf](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html):

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/di80q83xtamzae2c3c2i.png) 

So I was like “Nice, seems like a good time to upgrade my Word-Search game to start using it.”, but [other interesting things](https://dev.to/mbarzeev/aggregating-unit-test-coverage-for-all-monorepos-packages-20c6) drew my attention, and so here we are now - upgrading to React 18. Let’s go!

My [Word-Search game](https://word-search-react-game.netlify.app/) is a project which started (and continued on) as a Create-React-App project and is currently using React 16.9.0 (:scream:). 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](https://github.com/reactwg/react-18/discussions/4), and surely enough they've taken me into another document which explains [upgrading to React 18 on the client](https://github.com/reactwg/react-18/discussions/6). 
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:

```bash
npm install react@latest react-dom@latest
```

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

I’m heading down to the [React Conf recap](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html) 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](https://github.com/reactwg/react-18/discussions/9) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dc43eb38yb37272mrf8h.png) 

No worries - let’s install the release candidate -

```bash
npm install react@rc react-dom@rc
```

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

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

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:

```json
"jsx": "react"
```

It is:

```json
"jsx": "react-jsx"
```

Reading the [TS docs](https://www.typescriptlang.org/tsconfig#jsx) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xy0hygpn6sty9bc51n74.png) 

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

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

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

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

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

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

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

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:

```bash
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
```

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

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

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 <a href="https://twitter.com/mattibarzeev?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">@mattibarzeev</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> on Twitter* :beers:

<small><small><small>Photo by <a href="https://unsplash.com/@lindsayhenwood?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Lindsay  Henwood</a> on <a href="https://unsplash.com/s/photos/step-up?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></small></small></small>