It’s been an eternity, technology speaking, since we received a major upgrade on ReactJS. The React team has announced v17 Release Candidate:
The React 17 release is unusual because it doesn’t add any new developer-facing features.
https://reactjs.org/blog/2020/08/10/react-v17-rc.html
This release comes with no new features. New upgrades are always shined up with new hot features, right? What gives?
I’d say this is a very worth while upgrade that teams should be seriously considering.
Fun fact: version numbering is a standard practice held in the software development community. To make a major release, that is, the first big number in a version, i.e. 17.0.0, implies this will break something. The second number is a minor version, i.e. 17.1.0, 17.22.0, etc. It adds new capabilities, but shouldn’t break existing capabilities. Sometimes you’ll see a third number, i.e. 17.1.4, 17.22.6, this is a patch version, normally used for fixing bugs. Geek out more at https://semver.org/. With all that said, for React to release a major version, something should be changing, even breaking… read on…
The new Feature in React 17
There is one big feature here that is well worth it. Well, two, I’ll share the smaller one a little later. The big update here is that this release will enable you to upgrade your app to future releases real easily. So easy, in fact, that you won’t have to upgrade your entire app! You could upgrade to v18 for just a portion of your app, while the core runs on v17. This is a “feature” in my book, and well worth a serious look for any dev team.
“The first option will be to upgrade your whole app at once, like you might have done before. But you will also have an option to upgrade your app piece by piece. For example, you might decide to migrate most of your app to React 18, but keep some lazy-loaded dialog or a subroute on React 17.”
https://reactjs.org/blog/2020/08/10/react-v17-rc.html#gradual-upgrades
Ya, really. Supporting multiple versions of React has been possible before, but with React 17, we’re seeing it’s much more easily done. Check out their sample repo, pretty clean and straightforward. You do have to get into 17 to support this new feature. This will be supported with v17 onward. Once there, THEN it gets easy to upgrade.
Impressively, they “only had to change fewer than twenty components out of 100,000+ so we expect that most apps can upgrade to React 17 without too much trouble” src This is good news! Less breaking changes make upgrades easier. There’s a small list of breaking changes below.
Do I have to upgrade it in pieces?
No, you can do a wholesale upgrade into 18, 19, 22, etc. For many teams this is viable solution, take a sprint and do an upgrade, boom, done. However, for many other teams, they may be working on older React code, apps that aren’t being maintained, or up to date. Sometimes upgrades on large applications will take a significant effort to test and assure nothing is broken.
This is where React 17 can shine! We can slowly upgrade pieces as we go, and take as much time as we need to fully move into React 18 and beyond.
Nothing is free…
Of course there are costs to splitting your application into versions. Development teams should think through if it’s worth the effort, or wait and do a full upgrade at a later point.
I have not experienced a code set being split between two different versions, but from what I can guess, there will be some headaches.
I think one of the biggest challenges will be the people. You and your team will have to be aware of what code is on what version, and know the differences between the two versions, for example, what capability to use under what version. This will probably bring some confusion for quite some time. Oh yea, that’s a v18 feature, but this component is on the v17 side, so should I move it or rethink it for v17?
I have found many enterprise dev shops are super slow in upgrading tech because of the learning curve, or it not being prioritized by the business since “if it’s not broken, don’t fix it”. Like any good change, how you manage that change is important, your developers are “users” too, users of a tech stack. Be strategic about the change, bring along training and experiences that will enable them to be successful.
Your end users, your visitors on our app, will need to download both React versions. Before you scream and throw the baby out with the bath water, you can lazy load the other version. Depending on your upgrade strategy, you could lazy load a library version as the user is using the app, without them knowing. Still not ideal, BUT you get to run both versions.
I’m sure there will be some fun technical problems with other library versions, like redux, jest, bootstrap, etc. that may work on one version, and not on another. It looks like each version will have its own package.json file to manage these dependencies. I’m unsure how they will all play together, nicely. Something worth testing and building out a proof of concept before committing.
Since this new capability is being released with v17, we won’t experience too many problems with code splitting until we get v18 and later released. Upgrading now does not force you to use code splitting.
What do you think? What other challenges are there with this approach? Please feel free to comment below or tag me on Twitter, I’d love to learn more for myself and my teams.
It’s not just about code splitting
Although that is the big feature, that’s not all 17 is about. As mentioned before, with any major version, there are breaking changes. There are a list of small breaking changes and improvements worth reviewing to see how they might impact your application.
- Aligning with browsers “made a couple of smaller changes related to the event system”
- No Event Pooling “React 17 removes the “event pooling” optimization from React.”
- Effect Cleanup Timing “We are making the timing of the
useEffect
cleanup function more consistent.” - Consistent Errors for Returning Undefined “In React 17, the behavior for forwardRef and memo components is consistent with regular function and class components. Returning undefined from them is an error.”
- Native Component Stacks – 😮😀 I’m excited for this one. This is the other reason I think an upgrade is worth it. Just coming off a week of debugging hell… “In React 17, the component stacks are generated using a different mechanism that stitches them together from the regular native JavaScript stacks. This lets you get the fully symbolicated React component stack traces in a production environment.“
- Removing Private Exports “these private exports have been removed. As far as we’re aware, React Native for Web was the only project using them”
You can review the comprehensive change log here as well.
To upgrade or not…
Short answer, YES.
npm install react@17.0.0-rc.0 react-dom@17.0.0-rc.0
Done yet? 😉
Eventually, 16 will be end of life and no longer supported. It is easier to keep up to date with versions than wait and then do a 2 or 3 version upgrade. That hurts, and is usually poorly documented because most people don’t jump that far.
You don’t have to upgrade to v17 now, certainly not using their release candidate. Seriously consider 17.1, or 17.2. Sometimes letting them iron out some wrinkles is best. I’ll be watching this closely and will push my team to upgrade once 17.1 is out.
Again, you don’t have to do the multiple versions route later on. The React team recommends to not use multiple versions, “Always prefer using one React if you can” src. The code splitting approach is great, if it’s needed. Make sure to weigh the pros and cons, and TEST TEST TEST!
I’ve been waiting for Concurrent Mode for quite some time, as I’m sure many have. If getting into v17 will allow me an easier upgrade to whatever version Concurrent Mode is on, sign me up!
Sources:
The ability to run dual versions is sweet.