Skip to content

Commit 2376f14

Browse files
committed
Support ref without initializer
1 parent 4d6e48f commit 2376f14

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## Unreleased
22

3+
- Fixed
4+
- Don't fail if user-defined class field (e.g. `this.foo`) is assigned without initializing.
5+
36
## 0.1.7
47

58
- Added

src/analysis/user_defined.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export type UserDefinedRef = {
5656
export type UserDefinedDirectRef = {
5757
type: "user_defined_direct_ref";
5858
localName?: string | undefined;
59-
init: NodePath<Expression>;
59+
init: NodePath<Expression> | undefined;
6060
typeAnnotation?: NodePath<TSType> | undefined;
6161
sites: ClassFieldSite[];
6262
};
@@ -204,15 +204,13 @@ export function analyzeUserDefined(
204204
typeAnnotation: refInitType1 ?? refInitType2,
205205
sites: field.sites,
206206
});
207-
} else if (valInit) {
207+
} else {
208208
fields.set(name, {
209209
type: "user_defined_direct_ref",
210210
init: valInit,
211211
typeAnnotation: valInitType,
212212
sites: field.sites,
213213
});
214-
} else {
215-
throw new AnalysisError(`Cannot transform this.${name}`);
216214
}
217215
}
218216

src/index.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,35 @@ describe("react-declassify", () => {
991991
expect(transform(input)).toBe(output);
992992
});
993993

994+
it("transforms class field without initializer as useRef", () => {
995+
const input = dedent`\
996+
class C extends React.Component {
997+
constructor(props) {
998+
super(props);
999+
}
1000+
1001+
foo() {
1002+
console.log(this.div);
1003+
}
1004+
1005+
render() {
1006+
return <div ref={(elem) => this.div = elem} />;
1007+
}
1008+
}
1009+
`;
1010+
const output = dedent`\
1011+
const C = () => {
1012+
function foo() {
1013+
console.log(div.current);
1014+
}
1015+
1016+
const div = React.useRef(undefined);
1017+
return <div ref={(elem) => div.current = elem} />;
1018+
};
1019+
`;
1020+
expect(transform(input)).toBe(output);
1021+
});
1022+
9941023
it("transforms typed class field as useRef", () => {
9951024
const input = dedent`\
9961025
class C extends React.Component {

src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,11 @@ function transformClass(analysis: AnalysisResult, options: { ts: boolean }, babe
317317
// const foo = useRef(init);
318318
const call = t.callExpression(
319319
getReactImport("useRef", babel, analysis.superClassRef),
320-
[field.init.node]
320+
[
321+
field.init
322+
? field.init.node
323+
: t.identifier("undefined")
324+
]
321325
);
322326
preamble.push(t.variableDeclaration(
323327
"const",

0 commit comments

Comments
 (0)