Skip to content

Commit 6bda4bf

Browse files
authored
refactor: Undeprecate hooks-extra-no-direct-set-state-in-use-layout-effect and remove it from recommended presets, closes #839 (#840)
1 parent 562a002 commit 6bda4bf

10 files changed

+1319
-80
lines changed

Diff for: packages/plugins/eslint-plugin-react-hooks-extra/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable perfectionist/sort-objects */
22
import { name, version } from "../package.json";
33
import noDirectSetStateInUseEffect from "./rules/no-direct-set-state-in-use-effect";
4+
import noDirectSetStateInUseLayoutEffect from "./rules/no-direct-set-state-in-use-layout-effect";
45
import noRedundantCustomHook from "./rules/no-redundant-custom-hook";
56
import ensureUseCallbackHasNonEmptyDeps from "./rules/no-unnecessary-use-callback";
67
import noUnnecessaryUseMemo from "./rules/no-unnecessary-use-memo";
@@ -13,6 +14,7 @@ export default {
1314
},
1415
rules: {
1516
"no-direct-set-state-in-use-effect": noDirectSetStateInUseEffect,
17+
"no-direct-set-state-in-use-layout-effect": noDirectSetStateInUseLayoutEffect,
1618
"no-redundant-custom-hook": noRedundantCustomHook,
1719
"no-unnecessary-use-callback": ensureUseCallbackHasNonEmptyDeps,
1820
"no-unnecessary-use-memo": noUnnecessaryUseMemo,
@@ -22,7 +24,5 @@ export default {
2224
"ensure-custom-hooks-using-other-hooks": noRedundantCustomHook,
2325
/** @deprecated Use `no-unnecessary-use-memo` instead */
2426
"ensure-use-memo-has-non-empty-deps": noUnnecessaryUseMemo,
25-
/** @deprecated Use `no-direct-set-state-in-use-effect` instead */
26-
"no-direct-set-state-in-use-layout-effect": noDirectSetStateInUseEffect,
2727
},
2828
} as const;

Diff for: packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.spec.ts

+15-55
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,6 @@ ruleTester.run(RULE_NAME, rule, {
1919
{ messageId: "noDirectSetStateInUseEffect" },
2020
],
2121
},
22-
{
23-
code: /* tsx */ `
24-
import { useLayoutEffect, useState } from "react";
25-
26-
function Component() {
27-
const [data, setData] = useState(0);
28-
useLayoutEffect(() => {
29-
setData(1);
30-
}, []);
31-
return null;
32-
}
33-
`,
34-
errors: [
35-
{ messageId: "noDirectSetStateInUseEffect" },
36-
],
37-
},
38-
{
39-
code: /* tsx */ `
40-
import { useInsertionEffect, useState } from "react";
41-
42-
function Component() {
43-
const [data, setData] = useState(0);
44-
useInsertionEffect(() => {
45-
setData(1);
46-
}, []);
47-
return null;
48-
}
49-
`,
50-
errors: [
51-
{ messageId: "noDirectSetStateInUseEffect" },
52-
],
53-
},
54-
{
55-
code: /* tsx */ `
56-
import { useState } from "react";
57-
58-
function Component() {
59-
const [data, setData] = useState(0);
60-
useIsomorphicLayoutEffect(() => {
61-
setData(1);
62-
}, []);
63-
return null;
64-
}
65-
`,
66-
errors: [
67-
{ messageId: "noDirectSetStateInUseEffect" },
68-
],
69-
settings: {
70-
"react-x": {
71-
additionalHooks: {
72-
useLayoutEffect: ["useIsomorphicLayoutEffect"],
73-
},
74-
},
75-
},
76-
},
7722
{
7823
code: /* tsx */ `
7924
import { useEffect, useState } from "react";
@@ -825,5 +770,20 @@ ruleTester.run(RULE_NAME, rule, {
825770
}, [handlerWatcher])
826771
}
827772
`,
773+
/* tsx */ `
774+
import { useLayoutEffect, useState, useRef } from "react";
775+
776+
function Tooltip() {
777+
const ref = useRef(null);
778+
const [tooltipHeight, setTooltipHeight] = useState(0); // You don't know real height yet
779+
780+
useLayoutEffect(() => {
781+
const { height } = ref.current.getBoundingClientRect();
782+
setTooltipHeight(height); // Re-render now that you know the real height
783+
}, []);
784+
785+
// ...use tooltipHeight in the rendering logic below...
786+
}
787+
`,
828788
],
829789
});

Diff for: packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.ts

+1-11
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,7 @@ export default createRule<[], MessageID>({
4040
if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
4141
const settings = decodeSettings(context.settings);
4242
const additionalHooks = settings.additionalHooks ?? {};
43-
const isUseEffectLikeCall = isReactHookCallWithNameAlias(
44-
"useEffect",
45-
context,
46-
[
47-
"useLayoutEffect",
48-
"useInsertionEffect",
49-
...additionalHooks.useEffect ?? [],
50-
...additionalHooks.useLayoutEffect ?? [],
51-
...additionalHooks.useInsertionEffect ?? [],
52-
],
53-
);
43+
const isUseEffectLikeCall = isReactHookCallWithNameAlias("useEffect", context, additionalHooks.useEffect ?? []);
5444
const isUseStateCall = isReactHookCallWithNameAlias("useState", context, additionalHooks.useState ?? []);
5545
const isUseMemoCall = isReactHookCallWithNameAlias("useMemo", context, additionalHooks.useMemo ?? []);
5646
const isUseCallbackCall = isReactHookCallWithNameAlias("useCallback", context, additionalHooks.useCallback ?? []);

0 commit comments

Comments
 (0)