Skip to content

Commit dbed970

Browse files
authored
Upgrade to react 19 (#610)
* 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
1 parent a789648 commit dbed970

File tree

4 files changed

+70
-63
lines changed

4 files changed

+70
-63
lines changed

babel.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = function (api) {
88
[
99
'@babel/preset-react',
1010
{
11+
runtime: 'automatic',
1112
development: !isProductionEnv,
1213
useBuiltIns: true,
1314
},

client/app/bundles/comments/components/CommentBox/CommentForm/CommentForm.jsx

+34-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* eslint-disable react/no-find-dom-node, react/no-string-refs */
22
import React from 'react';
33
import PropTypes from 'prop-types';
4-
import ReactDOM from 'react-dom';
54
import { CSSTransition, TransitionGroup } from 'react-transition-group';
65
import _ from 'lodash';
76
import { injectIntl } from 'react-intl';
@@ -27,6 +26,13 @@ class CommentForm extends BaseComponent {
2726
comment: emptyComment,
2827
};
2928

29+
this.horizontalAuthorRef = React.createRef();
30+
this.horizontalTextRef = React.createRef();
31+
this.stackedAuthorRef = React.createRef();
32+
this.stackedTextRef = React.createRef();
33+
this.inlineAuthorRef = React.createRef();
34+
this.inlineTextRef = React.createRef();
35+
3036
_.bindAll(this, ['handleSelect', 'handleChange', 'handleSubmit', 'resetAndFocus']);
3137
}
3238

@@ -40,22 +46,20 @@ class CommentForm extends BaseComponent {
4046
switch (this.state.formMode) {
4147
case 0:
4248
comment = {
43-
author: ReactDOM.findDOMNode(this.refs.horizontalAuthorNode).value,
44-
text: ReactDOM.findDOMNode(this.refs.horizontalTextNode).value,
49+
author: this.horizontalAuthorRef.current.value,
50+
text: this.horizontalTextRef.current.value,
4551
};
4652
break;
4753
case 1:
4854
comment = {
49-
author: ReactDOM.findDOMNode(this.refs.stackedAuthorNode).value,
50-
text: ReactDOM.findDOMNode(this.refs.stackedTextNode).value,
55+
author: this.stackedAuthorRef.current.value,
56+
text: this.stackedTextRef.current.value,
5157
};
5258
break;
5359
case 2:
5460
comment = {
55-
// This is different because the input is a native HTML element
56-
// rather than a React element.
57-
author: ReactDOM.findDOMNode(this.refs.inlineAuthorNode).value,
58-
text: ReactDOM.findDOMNode(this.refs.inlineTextNode).value,
61+
author: this.inlineAuthorRef.current.value,
62+
text: this.inlineTextRef.current.value,
5963
};
6064
break;
6165
default:
@@ -81,13 +85,13 @@ class CommentForm extends BaseComponent {
8185
let ref;
8286
switch (this.state.formMode) {
8387
case 0:
84-
ref = ReactDOM.findDOMNode(this.refs.horizontalTextNode);
88+
ref = this.horizontalTextRef.current;
8589
break;
8690
case 1:
87-
ref = ReactDOM.findDOMNode(this.refs.stackedTextNode);
91+
ref = this.stackedTextRef.current;
8892
break;
8993
case 2:
90-
ref = ReactDOM.findDOMNode(this.refs.inlineTextNode);
94+
ref = this.inlineTextRef.current;
9195
break;
9296
default:
9397
throw new Error(`Unexpected state.formMode ${this.state.formMode}`);
@@ -103,31 +107,31 @@ class CommentForm extends BaseComponent {
103107
<hr />
104108
<form className="form-horizontal flex flex-col gap-4" onSubmit={this.handleSubmit}>
105109
<div className="flex flex-col gap-0 items-center lg:gap-4 lg:flex-row">
106-
<label htmlFor="horizontalAuthorNode" className="w-full lg:w-2/12 lg:text-end shrink-0">
110+
<label htmlFor="horizontalAuthorRef" className="w-full lg:w-2/12 lg:text-end shrink-0">
107111
{formatMessage(defaultMessages.inputNameLabel)}
108112
</label>
109113
<input
110114
type="text"
111-
id="horizontalAuthorNode"
115+
id="horizontalAuthorRef"
112116
placeholder={formatMessage(defaultMessages.inputNamePlaceholder)}
113117
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
114-
ref="horizontalAuthorNode"
118+
ref={this.horizontalAuthorRef}
115119
value={this.state.comment.author}
116120
onChange={this.handleChange}
117121
disabled={this.props.isSaving}
118122
/>
119123
</div>
120124

121125
<div className="flex flex-col gap-0 items-center lg:gap-4 lg:flex-row">
122-
<label htmlFor="horizontalTextNode" className="w-full lg:w-2/12 lg:text-end shrink-0">
126+
<label htmlFor="horizontalTextRef" className="w-full lg:w-2/12 lg:text-end shrink-0">
123127
{formatMessage(defaultMessages.inputTextLabel)}
124128
</label>
125129
<input
126130
type="textarea"
127-
id="horizontalTextNode"
131+
id="horizontalTextRef"
128132
placeholder={formatMessage(defaultMessages.inputTextPlaceholder)}
129133
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
130-
ref="horizontalTextNode"
134+
ref={this.horizontalTextRef}
131135
value={this.state.comment.text}
132136
onChange={this.handleChange}
133137
disabled={this.props.isSaving}
@@ -158,31 +162,31 @@ class CommentForm extends BaseComponent {
158162
<hr />
159163
<form className="flex flex-col gap-4" onSubmit={this.handleSubmit}>
160164
<div className="flex flex-col gap-0">
161-
<label htmlFor="stackedAuthorNode" className="w-full">
165+
<label htmlFor="stackedAuthorRef" className="w-full">
162166
{formatMessage(defaultMessages.inputNameLabel)}
163167
</label>
164168
<input
165169
type="text"
166-
id="stackedAuthorNode"
170+
id="stackedAuthorRef"
167171
placeholder={formatMessage(defaultMessages.inputNamePlaceholder)}
168172
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
169-
ref="stackedAuthorNode"
173+
ref={this.stackedAuthorRef}
170174
value={this.state.comment.author}
171175
onChange={this.handleChange}
172176
disabled={this.props.isSaving}
173177
/>
174178
</div>
175179

176180
<div className="flex flex-col gap-0">
177-
<label htmlFor="stackedTextNode" className="w-full">
181+
<label htmlFor="stackedTextRef" className="w-full">
178182
{formatMessage(defaultMessages.inputTextLabel)}
179183
</label>
180184
<input
181185
type="text"
182-
id="stackedTextNode"
186+
id="stackedTextRef"
183187
placeholder={formatMessage(defaultMessages.inputTextPlaceholder)}
184188
className="px-3 py-1 leading-4 border border-gray-300 rounded w-full"
185-
ref="stackedTextNode"
189+
ref={this.stackedTextRef}
186190
value={this.state.comment.text}
187191
onChange={this.handleChange}
188192
disabled={this.props.isSaving}
@@ -213,27 +217,27 @@ class CommentForm extends BaseComponent {
213217
<hr />
214218
<form className="form-inline flex flex-col lg:flex-row flex-wrap gap-4" onSubmit={this.handleSubmit}>
215219
<div className="flex gap-2 items-center">
216-
<label htmlFor="inlineAuthorNode">{formatMessage(defaultMessages.inputNameLabel)}</label>
220+
<label htmlFor="inlineAuthorRef">{formatMessage(defaultMessages.inputNameLabel)}</label>
217221
<input
218222
type="text"
219-
id="inlineAuthorNode"
223+
id="inlineAuthorRef"
220224
placeholder={formatMessage(defaultMessages.inputNamePlaceholder)}
221225
className="px-3 py-1 leading-4 border border-gray-300 rounded"
222-
ref="inlineAuthorNode"
226+
ref={this.inlineAuthorRef}
223227
value={this.state.comment.author}
224228
onChange={this.handleChange}
225229
disabled={this.props.isSaving}
226230
/>
227231
</div>
228232

229233
<div className="flex gap-2 items-center">
230-
<label htmlFor="inlineTextNode">{formatMessage(defaultMessages.inputTextLabel)}</label>
234+
<label htmlFor="inlineTextRef">{formatMessage(defaultMessages.inputTextLabel)}</label>
231235
<input
232236
type="textarea"
233-
id="inlineTextNode"
237+
id="inlineTextRef"
234238
placeholder={formatMessage(defaultMessages.inputTextPlaceholder)}
235239
className="px-3 py-1 leading-4 border border-gray-300 rounded"
236-
ref="inlineTextNode"
240+
ref={this.inlineTextRef}
237241
value={this.state.comment.text}
238242
onChange={this.handleChange}
239243
disabled={this.props.isSaving}

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@
7575
"postcss-loader": "7.3.3",
7676
"postcss-preset-env": "^8.5.0",
7777
"prop-types": "^15.8.1",
78-
"react": "^18.2.0",
79-
"react-dom": "^18.2.0",
78+
"react": "^19.0.0",
79+
"react-dom": "^19.0.0",
8080
"react-intl": "^6.4.4",
8181
"react-on-rails": "14.0.3",
8282
"react-redux": "^8.1.0",
@@ -86,7 +86,7 @@
8686
"react-transition-group": "4.4.5",
8787
"redux": "^4.2.1",
8888
"redux-thunk": "^2.2.0",
89-
"rescript": "^10.1.4",
89+
"rescript": "^11.1.4",
9090
"rescript-react-on-rails": "^1.0.1",
9191
"resolve-url-loader": "^2.2.0",
9292
"sanitize-html": "^2.11.0",

yarn.lock

+32-30
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,14 @@
10141014
core-js-pure "^3.30.2"
10151015
regenerator-runtime "^0.14.0"
10161016

1017-
"@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":
1017+
"@babel/runtime@^7.12.1":
1018+
version "7.26.0"
1019+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
1020+
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
1021+
dependencies:
1022+
regenerator-runtime "^0.14.0"
1023+
1024+
"@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":
10181025
version "7.22.10"
10191026
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682"
10201027
integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==
@@ -5901,7 +5908,7 @@ loglevel@^1.4.1:
59015908
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
59025909
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==
59035910

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

7239-
react-dom@^18.2.0:
7240-
version "18.2.0"
7241-
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
7242-
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
7246+
react-dom@^19.0.0:
7247+
version "19.0.0"
7248+
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57"
7249+
integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==
72437250
dependencies:
7244-
loose-envify "^1.1.0"
7245-
scheduler "^0.23.0"
7251+
scheduler "^0.25.0"
72467252

72477253
react-intl@^6.4.4:
72487254
version "6.4.4"
@@ -7286,9 +7292,9 @@ react-proxy@^1.1.7:
72867292
react-deep-force-update "^1.0.0"
72877293

72887294
react-redux@^8.1.0:
7289-
version "8.1.2"
7290-
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.2.tgz#9076bbc6b60f746659ad6d51cb05de9c5e1e9188"
7291-
integrity sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==
7295+
version "8.1.3"
7296+
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.3.tgz#4fdc0462d0acb59af29a13c27ffef6f49ab4df46"
7297+
integrity sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==
72927298
dependencies:
72937299
"@babel/runtime" "^7.12.1"
72947300
"@types/hoist-non-react-statics" "^3.3.1"
@@ -7340,12 +7346,10 @@ [email protected]:
73407346
loose-envify "^1.4.0"
73417347
prop-types "^15.6.2"
73427348

7343-
react@^18.2.0:
7344-
version "18.2.0"
7345-
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
7346-
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
7347-
dependencies:
7348-
loose-envify "^1.1.0"
7349+
react@^19.0.0:
7350+
version "19.0.0"
7351+
resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd"
7352+
integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==
73497353

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

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

75187522
resolve-cwd@^3.0.0:
75197523
version "3.0.0"
@@ -7696,12 +7700,10 @@ sass@^1.58.3:
76967700
immutable "^4.0.0"
76977701
source-map-js ">=0.6.2 <2.0.0"
76987702

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

77067708
schema-utils@^3.0, schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0:
77077709
version "3.3.0"
@@ -8494,9 +8496,9 @@ url-loader@^4.1.1:
84948496
schema-utils "^3.0.0"
84958497

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

85018503
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
85028504
version "1.0.2"

0 commit comments

Comments
 (0)