carbon
carbon copied to clipboard
Support React 18
Desired behaviour
Background
This feature request is to add support for React 18. Ideally, the peerDependencies
of carbon-react
would be:
"react": "^17 || ^18",
"react-dom": "^17 || ^18",
"styled-components": "^6"
...
Why support React 18?
Improved Server-Side Rendering (SSR): React 18 enhances server-side rendering capabilities, making it more efficient and performant. This is particularly beneficial for applications requiring fast initial renders and improved SEO.
Concurrent Rendering: React 18 introduces concurrent rendering, allowing the application to work on multiple tasks simultaneously. This improves the app's responsiveness and user experience, especially in scenarios with complex and time-consuming computations.
Community and Ecosystem Support: React 18 was released in March 2022. A lot of innovation in the React space has occurred during that time. Modern frameworks Remix and Next only support React 18. With the recent introduction of Remix's SPA mode (https://github.com/remix-run/remix/blob/main/CHANGELOG.md#v250), there are no more blockers for typical SPA to adopt these modern technologies.
Automatic Batching of Updates: With React 18, updates are automatically batched, reducing the number of renders and enhancing performance. This ensures that the UI remains smooth and responsive despite frequent state changes.
Transitions with React Server Components: React 18 introduces server components, enabling seamless transitions between the server and client. This improves rendering efficiency by offloading some components to the server, reducing the client-side load.
Improved Developer Experience: React 18 has improved tooling and developer experience. Features like Fast Refresh enhancements and improved error messages make debugging and development more efficient and enjoyable.
Automatic State Serialization: React 18 introduces automatic state serialization, making maintaining and sharing application states easier.
Enhanced Concurrent Mode Features: React 18 builds upon the foundation of Concurrent Mode, offering additional features and improvements. This includes features like useTransition
and startTransition
to control the priority of updates, providing more fine-grained control over rendering.
Blockers
Enzyme
From what I've gathered, most of the friction of supporting React 18 comes from the scale of Enzyme tests. Enzyme does not support React 18 (or React 17, for that matter). There is a highly experimental adapter community adapter that can be tested: https://www.npmjs.com/package/@cfaester/enzyme-adapter-react-18. However, the real answer for the project's health likely involves migrating from Enzyme. I understand that the team is working towards this path 👍🏻
styled-components
This library's current version of styled-components
is 4.4.1
. That version came out five years ago. Since then, styled-components
have made many upgrades to their library that pair well with React 18's new features like SSR. Accordingly, it may make sense to upgrade styled-components
to the latest version before the React 18 upgrade.
Breaking existing applications
Ideally, the upgrade would be transparent to consuming projects. Projects would likely have to upgrade their styled-components
from 4.4.1
to 6.x
. Afterwards, consuming projects may eventually adopt React 18 at their discretion.
Lots of work
I understand that this is a major undertaking. However, in my personal opinion, it's all important work to future-proof this library.
Current behaviour
I briefly tried to migrate our existing application from React 17 to React 18 by forcefully setting the version. Unfortunately, Carbon was unusable—events like onClick
were not registering for some components. I'd be happy to set up calls with engineers to walk through a failed upgraded version of React 18 to address some of these issues!
Suggested Solution
- Conduct a preliminary investigation round with a few Sage projects that attempt to upgrade to React 18 and write bug reports for issues that arise.
- Fix the bugs that arose during the preliminary investigations.
__ At this point, projects can consider adopting React 18 at their own risk. Projects wouldn't reasonably adopt SSR-related features, mostly focusing on improvements related to automatic batching updates, DX, and concurrent updates. __
- Upgrade
styled-components
tov6
. I suggest this to avoid writing extra migrations while converting Enzyme to RTL/Playwright. It's possible that many of the bugs related to upgrading React 18 come from not upgradingstyled-components
. Accordingly, it;s possible that this could be part of step 2.
__ At this point, projects can consider adopting React 18 SSR at their own risk. __
- Evaluate whether the stop-gap Enzyme adapter works https://www.npmjs.com/package/@cfaester/enzyme-adapter-react-18. If it does (at least partially), you can use it while you convert Enzyme tests that fail with the adapter work.
- Run your test suite with React 17 and React 18 in parallel. It's OK if React 18 tests fail in CI; at least you track progress!
- Make the React 18 tests pass.
- Bump
peerDependencies
to support React 18 😄
CodeSandbox or Storybook URL
No response
Anything else we should know?
No response
Confidentiality
- [X] I confirm there is no confidential or commercially sensitive information included.
Hi @quinnturner 👋🏼 Quick update on this, we are very eager to get to React 18, given it's a major piece of tech debt for us (see FE-6015).
Currently, we are handling an urgent Cypress to Playwright upgrade, so migrating Enzyme to RTL will be our next big epic, which should enable us to upgrade to React 18. We are hesitant to use the unofficial Enzyme adapter due to past issues with the React 17 adapter and Enzyme's legacy status, so like you mentioned I think dropping Enzyme completely is the best approach long-term.
As for styled-components
, we do want to investigate alternative solutions, like using CSS modules (see ticket FE-6017), to simplify our styling due to the unnecessary complexity we've faced using CSS-in-JS. An incentive for this would be [email protected]
no longer being required as a peer dependency for Carbon, meaning you should be able to upgrade to version 6 if you choose. Please bear in mind that we haven't investigated this yet so this isn't our official strategy, but we will provide an update if we think this would be worthwhile and get an RFC published.
If you have any further ideas or suggestions that would be helpful for you, feel free to us let know and we'll investigate it! 😄