Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fab9974

Browse files
authored
chore(website): Enable react-hooks exhaustive deps rules (typescript-eslint#5663)
* enable rules * fix warnings * add missing dependencies * fix infinite rerenders * fix expansion of tree items
1 parent 84e316b commit fab9974

15 files changed

+148
-81
lines changed

packages/website/.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ module.exports = {
2222
'react/jsx-no-target-blank': 'off',
2323
'react/no-unescaped-entities': 'off',
2424
'@typescript-eslint/internal/prefer-ast-types-enum': 'off',
25-
'react-hooks/exhaustive-deps': 'off', // TODO: enable it later
2625
},
2726
settings: {
2827
react: {

packages/website/src/components/ASTViewerTS.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,17 @@ export default function ASTViewerTS({
5353
['TypeFlags', typeFlags],
5454
);
5555
setModel(serialize(value, scopeSerializer));
56-
}, [value, syntaxKind]);
56+
}, [
57+
value,
58+
syntaxKind,
59+
nodeFlags,
60+
tokenFlags,
61+
modifierFlags,
62+
objectFlags,
63+
symbolFlags,
64+
flowFlags,
65+
typeFlags,
66+
]);
5767

5868
return (
5969
<ASTViewer position={position} onSelectNode={onSelectNode} value={model} />

packages/website/src/components/OptionsSelector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function OptionsSelectorContent({
5151
.then(() => {
5252
setCopyLink(true);
5353
});
54-
}, []);
54+
}, [setCopyLink]);
5555

5656
const copyMarkdownToClipboard = useCallback(() => {
5757
if (isLoading) {
@@ -60,7 +60,7 @@ function OptionsSelectorContent({
6060
void navigator.clipboard.writeText(createMarkdown(state)).then(() => {
6161
setCopyMarkdown(true);
6262
});
63-
}, [state, isLoading]);
63+
}, [isLoading, state, setCopyMarkdown]);
6464

6565
const openIssue = useCallback(() => {
6666
if (isLoading) {

packages/website/src/components/Playground.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ function Playground(): JSX.Element {
8484
[setState],
8585
);
8686

87+
const onLoaded = useCallback(
88+
(ruleNames: RuleDetails[], tsVersions: readonly string[]): void => {
89+
setRuleNames(ruleNames);
90+
setTSVersion(tsVersions);
91+
setIsLoading(false);
92+
},
93+
[],
94+
);
95+
8796
return (
8897
<div className={styles.codeContainer}>
8998
{ruleNames.length > 0 && (
@@ -150,11 +159,7 @@ function Playground(): JSX.Element {
150159
onMarkersChange={setMarkers}
151160
decoration={selectedRange}
152161
onChange={setState}
153-
onLoaded={(ruleNames, tsVersions): void => {
154-
setRuleNames(ruleNames);
155-
setTSVersion(tsVersions);
156-
setIsLoading(false);
157-
}}
162+
onLoaded={onLoaded}
158163
onSelect={setPosition}
159164
/>
160165
</div>

packages/website/src/components/ast/Elements.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function ComplexItem({
3030
}
3131
}
3232
},
33-
[data],
33+
[data.model.range, onSelectNode],
3434
);
3535

3636
useEffect(() => {
@@ -44,10 +44,10 @@ export function ComplexItem({
4444
level !== 'ast' && selected && !hasChildInRange(selection, data.model),
4545
);
4646

47-
if (selected && !isExpanded) {
47+
if (selected) {
4848
setIsExpanded(selected);
4949
}
50-
}, [selection, data]);
50+
}, [selection, data, level]);
5151

5252
return (
5353
<ItemGroup

packages/website/src/components/ast/PropertyName.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,23 @@ export interface PropertyNameProps {
1111
}
1212

1313
export default function PropertyName(props: PropertyNameProps): JSX.Element {
14+
const { onClick: onClickProps, onHover } = props;
15+
1416
const onClick = useCallback(
1517
(e: MouseEvent<HTMLElement>) => {
1618
e.preventDefault();
17-
props.onClick?.(e);
19+
onClickProps?.(e);
1820
},
19-
[props.onClick],
21+
[onClickProps],
2022
);
2123

2224
const onMouseEnter = useCallback(() => {
23-
props.onHover?.(true);
24-
}, [props.onHover]);
25+
onHover?.(true);
26+
}, [onHover]);
2527

2628
const onMouseLeave = useCallback(() => {
27-
props.onHover?.(false);
28-
}, [props.onHover]);
29+
onHover?.(false);
30+
}, [onHover]);
2931

3032
return props.onClick || props.onHover ? (
3133
<>

packages/website/src/components/ast/SimpleItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function SimpleItem({
2020
onSelectNode(state ? data.model.range : null);
2121
}
2222
},
23-
[data],
23+
[data.model.range, onSelectNode],
2424
);
2525

2626
return (

packages/website/src/components/config/ConfigEditor.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,26 +89,27 @@ function isDefault(value: unknown, defaults?: unknown[]): boolean {
8989
}
9090

9191
function ConfigEditor(props: ConfigEditorProps): JSX.Element {
92+
const { onClose: onCloseProps, isOpen, values } = props;
9293
const [filter, setFilter] = useState<string>('');
9394
const [config, setConfig] = useReducer(reducerObject, {});
9495
const [filterInput, setFilterFocus] = useFocus();
9596

9697
const onClose = useCallback(() => {
97-
props.onClose(config);
98-
}, [props.onClose, config]);
98+
onCloseProps(config);
99+
}, [onCloseProps, config]);
99100

100101
useEffect(() => {
101-
setConfig({ type: 'init', config: props.values });
102-
}, [props.values]);
102+
setConfig({ type: 'init', config: values });
103+
}, [values]);
103104

104105
useEffect(() => {
105-
if (props.isOpen) {
106+
if (isOpen) {
106107
setFilterFocus();
107108
}
108-
}, [props.isOpen]);
109+
}, [isOpen, setFilterFocus]);
109110

110111
return (
111-
<Modal header={props.header} isOpen={props.isOpen} onClose={onClose}>
112+
<Modal header={props.header} isOpen={isOpen} onClose={onClose}>
112113
<div className={styles.searchBar}>
113114
<Text
114115
ref={filterInput}

packages/website/src/components/config/ConfigEslint.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,21 @@ function checkOptions(rule: [string, unknown]): rule is [string, RuleEntry] {
2828
}
2929

3030
function ConfigEslint(props: ConfigEslintProps): JSX.Element {
31+
const { isOpen, config, onClose: onCloseProps, ruleOptions } = props;
3132
const [options, updateOptions] = useState<ConfigOptionsType[]>([]);
3233
const [configObject, updateConfigObject] = useState<EslintRC>();
3334

3435
useEffect(() => {
35-
if (props.isOpen) {
36-
updateConfigObject(parseESLintRC(props.config));
36+
if (isOpen) {
37+
updateConfigObject(parseESLintRC(config));
3738
}
38-
}, [props.isOpen, props.config]);
39+
}, [isOpen, config]);
3940

4041
useEffect(() => {
4142
updateOptions([
4243
{
4344
heading: 'Rules',
44-
fields: props.ruleOptions
45+
fields: ruleOptions
4546
.filter(item => item.name.startsWith('@typescript'))
4647
.map(item => ({
4748
key: item.name,
@@ -52,7 +53,7 @@ function ConfigEslint(props: ConfigEslintProps): JSX.Element {
5253
},
5354
{
5455
heading: 'Core rules',
55-
fields: props.ruleOptions
56+
fields: ruleOptions
5657
.filter(item => !item.name.startsWith('@typescript'))
5758
.map(item => ({
5859
key: item.name,
@@ -62,7 +63,7 @@ function ConfigEslint(props: ConfigEslintProps): JSX.Element {
6263
})),
6364
},
6465
]);
65-
}, [props.ruleOptions]);
66+
}, [ruleOptions]);
6667

6768
const onClose = useCallback(
6869
(newConfig: Record<string, unknown>) => {
@@ -76,22 +77,22 @@ function ConfigEslint(props: ConfigEslintProps): JSX.Element {
7677
.filter(checkOptions),
7778
);
7879
if (!shallowEqual(cfg, configObject?.rules)) {
79-
props.onClose({
80+
onCloseProps({
8081
eslintrc: toJson({ ...(configObject ?? {}), rules: cfg }),
8182
});
8283
} else {
83-
props.onClose();
84+
onCloseProps();
8485
}
8586
},
86-
[props.onClose, configObject],
87+
[onCloseProps, configObject],
8788
);
8889

8990
return (
9091
<ConfigEditor
9192
header="Eslint Config"
9293
options={options}
9394
values={configObject?.rules ?? {}}
94-
isOpen={props.isOpen}
95+
isOpen={isOpen}
9596
onClose={onClose}
9697
/>
9798
);

packages/website/src/components/config/ConfigTypeScript.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ interface ConfigTypeScriptProps {
1313
}
1414

1515
function ConfigTypeScript(props: ConfigTypeScriptProps): JSX.Element {
16+
const { onClose: onCloseProps, isOpen, config } = props;
1617
const [tsConfigOptions, updateOptions] = useState<ConfigOptionsType[]>([]);
1718
const [configObject, updateConfigObject] = useState<TSConfig>();
1819

1920
useEffect(() => {
20-
if (props.isOpen) {
21-
updateConfigObject(parseTSConfig(props.config));
21+
if (isOpen) {
22+
updateConfigObject(parseTSConfig(config));
2223
}
23-
}, [props.isOpen, props.config]);
24+
}, [isOpen, config]);
2425

2526
useEffect(() => {
2627
if (window.ts) {
@@ -54,28 +55,28 @@ function ConfigTypeScript(props: ConfigTypeScriptProps): JSX.Element {
5455
),
5556
);
5657
}
57-
}, [props.isOpen]);
58+
}, [isOpen]);
5859

5960
const onClose = useCallback(
6061
(newConfig: Record<string, unknown>) => {
6162
const cfg = { ...newConfig };
6263
if (!shallowEqual(cfg, configObject?.compilerOptions)) {
63-
props.onClose({
64+
onCloseProps({
6465
tsconfig: toJson({ ...(configObject ?? {}), compilerOptions: cfg }),
6566
});
6667
} else {
67-
props.onClose();
68+
onCloseProps();
6869
}
6970
},
70-
[props.onClose, configObject],
71+
[onCloseProps, configObject],
7172
);
7273

7374
return (
7475
<ConfigEditor
7576
header="TypeScript Config"
7677
options={tsConfigOptions}
7778
values={configObject?.compilerOptions ?? {}}
78-
isOpen={props.isOpen}
79+
isOpen={isOpen}
7980
onClose={onClose}
8081
/>
8182
);

0 commit comments

Comments
 (0)