Skip to content

Commit

Permalink
fix(react-19-replace-use-form-state): changed import from react-dom t…
Browse files Browse the repository at this point in the history
…o react (#1357)

* fix(react-19-replace-use-form-state): changed import from react-dom to react

* fix(react-19-replace-use-form-state): changed import from react-dom to react
  • Loading branch information
arybitskiy authored Oct 22, 2024
1 parent e7c78f8 commit 5041371
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"version": "1.0.6",
"name": "react/19/replace-use-form-state",
"private": false,
"version": "1.0.7",
"engine": "jscodeshift",
"meta": {
"git": "https://github.com/codemod-com/codemod/tree/main/packages/codemods/react/19/replace-use-form-state",
"tags": ["react", "migration"]
},
"private": false,
"applicability": {
"from": [["react", "<=", "18"]]
},
"arguments": [],
"meta": {
"tags": ["react", "migration"],
"git": "https://github.com/codemod-com/codemod/tree/main/packages/codemods/react/19/replace-use-form-state"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useActionState } from "react-dom";
import { useActionState } from "react";

async function increment(previousState, formData) {
return previousState + 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ReactDOM from "react-dom";
import { useActionState } from "react";

function StatefulForm({}) {
const [state, formAction] = ReactDOM.useActionState(increment, 0);
const [state, formAction] = useActionState(increment, 0);
return <form></form>;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ReactDOM from "react-dom";
import { useActionState } from "react";

function StatefulForm({}) {
const [state, formAction] = ReactDOM.useActionState(increment, 0);
const [state, formAction] = useActionState(increment, 0);
return <form></form>;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createPortal, useActionState } from "react-dom";
import { useActionState } from "react";
import { createPortal } from "react-dom";

function StatefulForm({}) {
const [state, formAction] = useActionState(increment, 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useActionState as UFS, createPortal } from "react-dom";
import { useActionState as UFS } from "react";
import { createPortal } from "react-dom";

function StatefulForm({}) {
const [state, formAction] = UFS(increment, 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codemod-com/codemod-react-replace-use-form-state",
"version": "1.0.0",
"version": "1.0.7",
"private": true,
"dependencies": {},
"devDependencies": {
Expand Down
66 changes: 50 additions & 16 deletions packages/codemods/react/19/replace-use-form-state/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,34 @@ export default function transform(
const root = j(file.source);

let isDirty = false;

function addImportDeclaration(name?: string) {
let importFromReact = root.find(j.ImportDeclaration, {
source: { value: "react" },
});
if (importFromReact.length === 0) {
isDirty = true;
root
.get()
.node.program.body.unshift(
j.importDeclaration(
[
name
? j.importSpecifier(
j.identifier("useActionState"),
name ? j.identifier(name) : undefined,
)
: j.importSpecifier(j.identifier("useActionState")),
],
j.literal("react"),
),
);
importFromReact = root.find(j.ImportDeclaration, {
source: { value: "react" },
});
}
}

// Get default import from react-dom
const defaultImportName = root
.find(j.ImportDeclaration, {
Expand Down Expand Up @@ -42,15 +70,23 @@ export default function transform(

if (actAccessExpressions.length > 0) {
// React import

actAccessExpressions.forEach((path) => {
j(path)
.find(j.Identifier, { name: "useFormState" })
.at(0)
?.replaceWith(() => {
isDirty = true;
return j.identifier("useActionState");
});
addImportDeclaration();
root
.find(j.ImportDeclaration, {
source: { value: "react-dom" },
specifiers: [{ type: "ImportDefaultSpecifier" }],
})
.remove();
root
.find(j.ImportDeclaration, {
source: { value: "react-dom" },
specifiers: [{ type: "ImportNamespaceSpecifier" }],
})
.remove();

actAccessExpressions.replaceWith(() => {
isDirty = true;
return j.identifier("useActionState");
});
}

Expand Down Expand Up @@ -78,13 +114,11 @@ export default function transform(
// Replace import name
reactDOMImportCollection
.find(j.ImportSpecifier, { imported: { name: "useFormState" } })
.replaceWith(() => {
isDirty = true;
return j.importSpecifier(
j.identifier("useActionState"),
j.identifier(usedName),
);
});
.remove();
if (reactDOMImportCollection.find(j.ImportSpecifier).length === 0) {
reactDOMImportCollection.remove();
}
addImportDeclaration(usedName);

// Means it's not aliased, so we also change identifier names, not only import
if (specifier?.local?.name === "useFormState") {
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5041371

Please sign in to comment.