Skip to content

Commit

Permalink
Upgrade to react 19 (#610)
Browse files Browse the repository at this point in the history
* upgrade to react 19.0

* enable modern JSX transform for React 19

this avoids this warning in console:
[SERVER] Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform

* upgrade to rescript 11 for compatibility with react 19

* refactor: migrate from string refs and findDOMNode to createRef()

Updates component to use React.createRef() to handle React 19 breaking changes:
- Replaces string refs with createRef
- Removes ReactDOM.findDOMNode usage
  • Loading branch information
ihab4real authored Jan 13, 2025
1 parent a789648 commit dbed970
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 63 deletions.
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = function (api) {
[
'@babel/preset-react',
{
runtime: 'automatic',
development: !isProductionEnv,
useBuiltIns: true,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable react/no-find-dom-node, react/no-string-refs */
import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import _ from 'lodash';
import { injectIntl } from 'react-intl';
Expand All @@ -27,6 +26,13 @@ class CommentForm extends BaseComponent {
comment: emptyComment,
};

this.horizontalAuthorRef = React.createRef();
this.horizontalTextRef = React.createRef();
this.stackedAuthorRef = React.createRef();
this.stackedTextRef = React.createRef();
this.inlineAuthorRef = React.createRef();
this.inlineTextRef = React.createRef();

_.bindAll(this, ['handleSelect', 'handleChange', 'handleSubmit', 'resetAndFocus']);
}

Expand All @@ -40,22 +46,20 @@ class CommentForm extends BaseComponent {
switch (this.state.formMode) {
case 0:
comment = {
author: ReactDOM.findDOMNode(this.refs.horizontalAuthorNode).value,
text: ReactDOM.findDOMNode(this.refs.horizontalTextNode).value,
author: this.horizontalAuthorRef.current.value,
text: this.horizontalTextRef.current.value,
};
break;
case 1:
comment = {
author: ReactDOM.findDOMNode(this.refs.stackedAuthorNode).value,
text: ReactDOM.findDOMNode(this.refs.stackedTextNode).value,
author: this.stackedAuthorRef.current.value,
text: this.stackedTextRef.current.value,
};
break;
case 2:
comment = {
// This is different because the input is a native HTML element
// rather than a React element.
author: ReactDOM.findDOMNode(this.refs.inlineAuthorNode).value,
text: ReactDOM.findDOMNode(this.refs.inlineTextNode).value,
author: this.inlineAuthorRef.current.value,
text: this.inlineTextRef.current.value,
};
break;
default:
Expand All @@ -81,13 +85,13 @@ class CommentForm extends BaseComponent {
let ref;
switch (this.state.formMode) {
case 0:
ref = ReactDOM.findDOMNode(this.refs.horizontalTextNode);
ref = this.horizontalTextRef.current;
break;
case 1:
ref = ReactDOM.findDOMNode(this.refs.stackedTextNode);
ref = this.stackedTextRef.current;
break;
case 2:
ref = ReactDOM.findDOMNode(this.refs.inlineTextNode);
ref = this.inlineTextRef.current;
break;
default:
throw new Error(`Unexpected state.formMode ${this.state.formMode}`);
Expand All @@ -103,31 +107,31 @@ class CommentForm extends BaseComponent {
<hr />
<form className="form-horizontal flex flex-col gap-4" onSubmit={this.handleSubmit}>
<div className="flex flex-col gap-0 items-center lg:gap-4 lg:flex-row">
<label htmlFor="horizontalAuthorNode" className="w-full lg:w-2/12 lg:text-end shrink-0">
<label htmlFor="horizontalAuthorRef" className="w-full lg:w-2/12 lg:text-end shrink-0">
{formatMessage(defaultMessages.inputNameLabel)}
</label>
<input
type="text"
id="horizontalAuthorNode"
id="horizontalAuthorRef"
placeholder={formatMessage(defaultMessages.inputNamePlaceholder)}
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
ref="horizontalAuthorNode"
ref={this.horizontalAuthorRef}
value={this.state.comment.author}
onChange={this.handleChange}
disabled={this.props.isSaving}
/>
</div>

<div className="flex flex-col gap-0 items-center lg:gap-4 lg:flex-row">
<label htmlFor="horizontalTextNode" className="w-full lg:w-2/12 lg:text-end shrink-0">
<label htmlFor="horizontalTextRef" className="w-full lg:w-2/12 lg:text-end shrink-0">
{formatMessage(defaultMessages.inputTextLabel)}
</label>
<input
type="textarea"
id="horizontalTextNode"
id="horizontalTextRef"
placeholder={formatMessage(defaultMessages.inputTextPlaceholder)}
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
ref="horizontalTextNode"
ref={this.horizontalTextRef}
value={this.state.comment.text}
onChange={this.handleChange}
disabled={this.props.isSaving}
Expand Down Expand Up @@ -158,31 +162,31 @@ class CommentForm extends BaseComponent {
<hr />
<form className="flex flex-col gap-4" onSubmit={this.handleSubmit}>
<div className="flex flex-col gap-0">
<label htmlFor="stackedAuthorNode" className="w-full">
<label htmlFor="stackedAuthorRef" className="w-full">
{formatMessage(defaultMessages.inputNameLabel)}
</label>
<input
type="text"
id="stackedAuthorNode"
id="stackedAuthorRef"
placeholder={formatMessage(defaultMessages.inputNamePlaceholder)}
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
ref="stackedAuthorNode"
ref={this.stackedAuthorRef}
value={this.state.comment.author}
onChange={this.handleChange}
disabled={this.props.isSaving}
/>
</div>

<div className="flex flex-col gap-0">
<label htmlFor="stackedTextNode" className="w-full">
<label htmlFor="stackedTextRef" className="w-full">
{formatMessage(defaultMessages.inputTextLabel)}
</label>
<input
type="text"
id="stackedTextNode"
id="stackedTextRef"
placeholder={formatMessage(defaultMessages.inputTextPlaceholder)}
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
ref="stackedTextNode"
ref={this.stackedTextRef}
value={this.state.comment.text}
onChange={this.handleChange}
disabled={this.props.isSaving}
Expand Down Expand Up @@ -213,27 +217,27 @@ class CommentForm extends BaseComponent {
<hr />
<form className="form-inline flex flex-col lg:flex-row flex-wrap gap-4" onSubmit={this.handleSubmit}>
<div className="flex gap-2 items-center">
<label htmlFor="inlineAuthorNode">{formatMessage(defaultMessages.inputNameLabel)}</label>
<label htmlFor="inlineAuthorRef">{formatMessage(defaultMessages.inputNameLabel)}</label>
<input
type="text"
id="inlineAuthorNode"
id="inlineAuthorRef"
placeholder={formatMessage(defaultMessages.inputNamePlaceholder)}
className="px-3 py-1 leading-4 border border-gray-300 rounded"
ref="inlineAuthorNode"
ref={this.inlineAuthorRef}
value={this.state.comment.author}
onChange={this.handleChange}
disabled={this.props.isSaving}
/>
</div>

<div className="flex gap-2 items-center">
<label htmlFor="inlineTextNode">{formatMessage(defaultMessages.inputTextLabel)}</label>
<label htmlFor="inlineTextRef">{formatMessage(defaultMessages.inputTextLabel)}</label>
<input
type="textarea"
id="inlineTextNode"
id="inlineTextRef"
placeholder={formatMessage(defaultMessages.inputTextPlaceholder)}
className="px-3 py-1 leading-4 border border-gray-300 rounded"
ref="inlineTextNode"
ref={this.inlineTextRef}
value={this.state.comment.text}
onChange={this.handleChange}
disabled={this.props.isSaving}
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@
"postcss-loader": "7.3.3",
"postcss-preset-env": "^8.5.0",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-intl": "^6.4.4",
"react-on-rails": "14.0.3",
"react-redux": "^8.1.0",
Expand All @@ -86,7 +86,7 @@
"react-transition-group": "4.4.5",
"redux": "^4.2.1",
"redux-thunk": "^2.2.0",
"rescript": "^10.1.4",
"rescript": "^11.1.4",
"rescript-react-on-rails": "^1.0.1",
"resolve-url-loader": "^2.2.0",
"sanitize-html": "^2.11.0",
Expand Down
62 changes: 32 additions & 30 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,14 @@
core-js-pure "^3.30.2"
regenerator-runtime "^0.14.0"

"@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.9", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
"@babel/runtime@^7.12.1":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
dependencies:
regenerator-runtime "^0.14.0"

"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.9", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.22.10"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682"
integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==
Expand Down Expand Up @@ -5901,7 +5908,7 @@ loglevel@^1.4.1:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==

loose-envify@^1.1.0, loose-envify@^1.4.0:
loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
Expand Down Expand Up @@ -7236,13 +7243,12 @@ react-deep-force-update@^1.0.0:
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1"
integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA==

react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
react-dom@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57"
integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.0"
scheduler "^0.25.0"

react-intl@^6.4.4:
version "6.4.4"
Expand Down Expand Up @@ -7286,9 +7292,9 @@ react-proxy@^1.1.7:
react-deep-force-update "^1.0.0"

react-redux@^8.1.0:
version "8.1.2"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.2.tgz#9076bbc6b60f746659ad6d51cb05de9c5e1e9188"
integrity sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==
version "8.1.3"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.3.tgz#4fdc0462d0acb59af29a13c27ffef6f49ab4df46"
integrity sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==
dependencies:
"@babel/runtime" "^7.12.1"
"@types/hoist-non-react-statics" "^3.3.1"
Expand Down Expand Up @@ -7340,12 +7346,10 @@ [email protected]:
loose-envify "^1.4.0"
prop-types "^15.6.2"

react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
react@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd"
integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==

read-cache@^1.0.0:
version "1.0.0"
Expand Down Expand Up @@ -7510,10 +7514,10 @@ rescript-react-on-rails@^1.0.1:
resolved "https://registry.yarnpkg.com/rescript-react-on-rails/-/rescript-react-on-rails-1.0.1.tgz#541dffdae64ec5053a50a3792b9db8783c959d1b"
integrity sha512-sbkDNCoiEWM9rqIiu+4joAj6W92yhM64KtLZQYfvYYm578jMcG02d98xpDeBT7MxZoPZZggFIed0m6Dj8bbDYA==

rescript@^10.1.4:
version "10.1.4"
resolved "https://registry.yarnpkg.com/rescript/-/rescript-10.1.4.tgz#0f37710d371f32a704f17b4e804f66ce3c79a305"
integrity sha512-FFKlS9AG/XrLepWsyw7B+A9DtQBPWEPDPDKghV831Y2KGbie+eeFBOS0xtRHp0xbt7S0N2Dm6hhX+kTZQ/3Ybg==
rescript@^11.1.4:
version "11.1.4"
resolved "https://registry.yarnpkg.com/rescript/-/rescript-11.1.4.tgz#9a42ebc4fc5363707e39cef5b3188160b63bee42"
integrity sha512-0bGU0bocihjSC6MsE3TMjHjY0EUpchyrREquLS8VsZ3ohSMD+VHUEwimEfB3kpBI1vYkw3UFZ3WD8R28guz/Vw==

resolve-cwd@^3.0.0:
version "3.0.0"
Expand Down Expand Up @@ -7696,12 +7700,10 @@ sass@^1.58.3:
immutable "^4.0.0"
source-map-js ">=0.6.2 <2.0.0"

scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
scheduler@^0.25.0:
version "0.25.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015"
integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==

schema-utils@^3.0, schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0:
version "3.3.0"
Expand Down Expand Up @@ -8494,9 +8496,9 @@ url-loader@^4.1.1:
schema-utils "^3.0.0"

use-sync-external-store@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
version "1.4.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==

util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2"
Expand Down

0 comments on commit dbed970

Please sign in to comment.