Skip to content

Commit 30fbd28

Browse files
committed
add to CLI, add dirty flag
1 parent fb4bc96 commit 30fbd28

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

bin/cli.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ const TRANSFORMER_INQUIRER_CHOICES = [
217217
'use-context-hook: Replaces useContext with React.use',
218218
value: 'use-context-hook'
219219
},
220+
{
221+
name:
222+
'replace-use-form-state: Replaces useFormState with useActionState',
223+
value: 'replace-use-form-state'
224+
},
220225
];
221226

222227
const PARSER_INQUIRER_CHOICES = [
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +0,0 @@
1-
import { other } from "react-dom";
2-
3-
function StatefulForm({}) {
4-
const otherResult = other();
5-
return <div></div>;
6-
}

transforms/replace-use-form-state.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export default function transform(
88
const j = api.jscodeshift;
99
const root = j(file.source);
1010

11+
let isDirty = false;
1112
// Get default import from react-dom
1213
const defaultImportName = root
1314
.find(j.ImportDeclaration, {
@@ -45,9 +46,11 @@ export default function transform(
4546
actAccessExpressions.forEach((path) => {
4647
j(path)
4748
.find(j.Identifier, { name: 'useFormState' })
48-
.paths()
4949
.at(0)
50-
?.replace(j.identifier('useActionState'));
50+
?.replaceWith(() => {
51+
isDirty = true;
52+
return j.identifier('useActionState');
53+
});
5154
});
5255
}
5356

@@ -59,37 +62,37 @@ export default function transform(
5962
const reactDOMImportPath = reactDOMImportCollection.paths().at(0);
6063

6164
if (!reactDOMImportPath) {
62-
return root.toSource();
65+
return isDirty ? root.toSource() : undefined;
6366
}
6467

6568
const specifier = reactDOMImportPath.node.specifiers?.find(
6669
(s) => s.type === 'ImportSpecifier' && s.imported.name === 'useFormState',
6770
);
6871

6972
if (!specifier || !j.ImportSpecifier.check(specifier)) {
70-
return root.toSource();
73+
return isDirty ? root.toSource() : undefined;
7174
}
7275

7376
const usedName = specifier.local?.name ?? specifier.imported.name;
7477

7578
// Replace import name
7679
reactDOMImportCollection
7780
.find(j.ImportSpecifier, { imported: { name: 'useFormState' } })
78-
.forEach((path) => {
79-
path.replace(
80-
j.importSpecifier(
81-
j.identifier('useActionState'),
82-
j.identifier(usedName),
83-
),
81+
.replaceWith(() => {
82+
isDirty = true;
83+
return j.importSpecifier(
84+
j.identifier('useActionState'),
85+
j.identifier(usedName),
8486
);
8587
});
8688

8789
// Means it's not aliased, so we also change identifier names, not only import
8890
if (specifier?.local?.name === 'useFormState') {
89-
root.find(j.Identifier, { name: 'useFormState' }).forEach((path) => {
90-
path.replace(j.identifier('useActionState'));
91+
root.find(j.Identifier, { name: 'useFormState' }).replaceWith(() => {
92+
isDirty = true;
93+
return j.identifier('useActionState');
9194
});
9295
}
9396

94-
return root.toSource();
97+
return isDirty ? root.toSource() : undefined;
9598
}

0 commit comments

Comments
 (0)