Skip to content

Commit 2a91f47

Browse files
committed
fix(eslint-plugin-react-hooks): remove experimental checks involving useEffectEvent
Contributing to #32240, this change removes the experimental `useEffectEvent` checks in the two react hooks eslint rule. As the api is refined, and the compiler rule(s) are incorporated into this plugin, these checks will be covered then.
1 parent 829401d commit 2a91f47

File tree

4 files changed

+2
-358
lines changed

4 files changed

+2
-358
lines changed

packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7675,62 +7675,6 @@ const tests = {
76757675
],
76767676
};
76777677

7678-
if (__EXPERIMENTAL__) {
7679-
tests.valid = [
7680-
...tests.valid,
7681-
{
7682-
code: normalizeIndent`
7683-
function MyComponent({ theme }) {
7684-
const onStuff = useEffectEvent(() => {
7685-
showNotification(theme);
7686-
});
7687-
useEffect(() => {
7688-
onStuff();
7689-
}, []);
7690-
}
7691-
`,
7692-
},
7693-
];
7694-
7695-
tests.invalid = [
7696-
...tests.invalid,
7697-
{
7698-
code: normalizeIndent`
7699-
function MyComponent({ theme }) {
7700-
const onStuff = useEffectEvent(() => {
7701-
showNotification(theme);
7702-
});
7703-
useEffect(() => {
7704-
onStuff();
7705-
}, [onStuff]);
7706-
}
7707-
`,
7708-
errors: [
7709-
{
7710-
message:
7711-
'Functions returned from `useEffectEvent` must not be included in the dependency array. ' +
7712-
'Remove `onStuff` from the list.',
7713-
suggestions: [
7714-
{
7715-
desc: 'Remove the dependency `onStuff`',
7716-
output: normalizeIndent`
7717-
function MyComponent({ theme }) {
7718-
const onStuff = useEffectEvent(() => {
7719-
showNotification(theme);
7720-
});
7721-
useEffect(() => {
7722-
onStuff();
7723-
}, []);
7724-
}
7725-
`,
7726-
},
7727-
],
7728-
},
7729-
],
7730-
},
7731-
];
7732-
}
7733-
77347678
// Tests that are only valid/invalid across parsers supporting Flow
77357679
const testsFlow = {
77367680
valid: [

packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js

Lines changed: 0 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,181 +1286,6 @@ const tests = {
12861286
],
12871287
};
12881288

1289-
if (__EXPERIMENTAL__) {
1290-
tests.valid = [
1291-
...tests.valid,
1292-
{
1293-
code: normalizeIndent`
1294-
// Valid because functions created with useEffectEvent can be called in a useEffect.
1295-
function MyComponent({ theme }) {
1296-
const onClick = useEffectEvent(() => {
1297-
showNotification(theme);
1298-
});
1299-
useEffect(() => {
1300-
onClick();
1301-
});
1302-
}
1303-
`,
1304-
},
1305-
{
1306-
code: normalizeIndent`
1307-
// Valid because functions created with useEffectEvent can be called in closures.
1308-
function MyComponent({ theme }) {
1309-
const onClick = useEffectEvent(() => {
1310-
showNotification(theme);
1311-
});
1312-
return <Child onClick={() => onClick()}></Child>;
1313-
}
1314-
`,
1315-
},
1316-
{
1317-
code: normalizeIndent`
1318-
// Valid because functions created with useEffectEvent can be called in closures.
1319-
function MyComponent({ theme }) {
1320-
const onClick = useEffectEvent(() => {
1321-
showNotification(theme);
1322-
});
1323-
const onClick2 = () => { onClick() };
1324-
const onClick3 = useCallback(() => onClick(), []);
1325-
return <>
1326-
<Child onClick={onClick2}></Child>
1327-
<Child onClick={onClick3}></Child>
1328-
</>;
1329-
}
1330-
`,
1331-
},
1332-
{
1333-
code: normalizeIndent`
1334-
// Valid because functions created with useEffectEvent can be passed by reference in useEffect
1335-
// and useEffectEvent.
1336-
function MyComponent({ theme }) {
1337-
const onClick = useEffectEvent(() => {
1338-
showNotification(theme);
1339-
});
1340-
const onClick2 = useEffectEvent(() => {
1341-
debounce(onClick);
1342-
});
1343-
useEffect(() => {
1344-
let id = setInterval(onClick, 100);
1345-
return () => clearInterval(onClick);
1346-
}, []);
1347-
return <Child onClick={() => onClick2()} />
1348-
}
1349-
`,
1350-
},
1351-
{
1352-
code: normalizeIndent`
1353-
const MyComponent = ({theme}) => {
1354-
const onClick = useEffectEvent(() => {
1355-
showNotification(theme);
1356-
});
1357-
return <Child onClick={() => onClick()}></Child>;
1358-
};
1359-
`,
1360-
},
1361-
{
1362-
code: normalizeIndent`
1363-
function MyComponent({ theme }) {
1364-
const notificationService = useNotifications();
1365-
const showNotification = useEffectEvent((text) => {
1366-
notificationService.notify(theme, text);
1367-
});
1368-
const onClick = useEffectEvent((text) => {
1369-
showNotification(text);
1370-
});
1371-
return <Child onClick={(text) => onClick(text)} />
1372-
}
1373-
`,
1374-
},
1375-
{
1376-
code: normalizeIndent`
1377-
function MyComponent({ theme }) {
1378-
useEffect(() => {
1379-
onClick();
1380-
});
1381-
const onClick = useEffectEvent(() => {
1382-
showNotification(theme);
1383-
});
1384-
}
1385-
`,
1386-
},
1387-
];
1388-
tests.invalid = [
1389-
...tests.invalid,
1390-
{
1391-
code: normalizeIndent`
1392-
function MyComponent({ theme }) {
1393-
const onClick = useEffectEvent(() => {
1394-
showNotification(theme);
1395-
});
1396-
return <Child onClick={onClick}></Child>;
1397-
}
1398-
`,
1399-
errors: [useEffectEventError('onClick')],
1400-
},
1401-
{
1402-
code: normalizeIndent`
1403-
// This should error even though it shares an identifier name with the below
1404-
function MyComponent({theme}) {
1405-
const onClick = useEffectEvent(() => {
1406-
showNotification(theme)
1407-
});
1408-
return <Child onClick={onClick} />
1409-
}
1410-
1411-
// The useEffectEvent function shares an identifier name with the above
1412-
function MyOtherComponent({theme}) {
1413-
const onClick = useEffectEvent(() => {
1414-
showNotification(theme)
1415-
});
1416-
return <Child onClick={() => onClick()} />
1417-
}
1418-
`,
1419-
errors: [{...useEffectEventError('onClick'), line: 7}],
1420-
},
1421-
{
1422-
code: normalizeIndent`
1423-
const MyComponent = ({ theme }) => {
1424-
const onClick = useEffectEvent(() => {
1425-
showNotification(theme);
1426-
});
1427-
return <Child onClick={onClick}></Child>;
1428-
}
1429-
`,
1430-
errors: [useEffectEventError('onClick')],
1431-
},
1432-
{
1433-
code: normalizeIndent`
1434-
// Invalid because onClick is being aliased to foo but not invoked
1435-
function MyComponent({ theme }) {
1436-
const onClick = useEffectEvent(() => {
1437-
showNotification(theme);
1438-
});
1439-
let foo = onClick;
1440-
return <Bar onClick={foo} />
1441-
}
1442-
`,
1443-
errors: [{...useEffectEventError('onClick'), line: 7}],
1444-
},
1445-
{
1446-
code: normalizeIndent`
1447-
// Should error because it's being passed down to JSX, although it's been referenced once
1448-
// in an effect
1449-
function MyComponent({ theme }) {
1450-
const onClick = useEffectEvent(() => {
1451-
showNotification(them);
1452-
});
1453-
useEffect(() => {
1454-
setTimeout(onClick, 100);
1455-
});
1456-
return <Child onClick={onClick} />
1457-
}
1458-
`,
1459-
errors: [useEffectEventError('onClick')],
1460-
},
1461-
];
1462-
}
1463-
14641289
function conditionalError(hook, hasPreviousFinalizer = false) {
14651290
return {
14661291
message:
@@ -1518,14 +1343,6 @@ function classError(hook) {
15181343
};
15191344
}
15201345

1521-
function useEffectEventError(fn) {
1522-
return {
1523-
message:
1524-
`\`${fn}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
1525-
'the same component. They cannot be assigned to variables or passed down.',
1526-
};
1527-
}
1528-
15291346
function asyncComponentHookError(fn) {
15301347
return {
15311348
message: `React Hook "${fn}" cannot be called in an async function.`,

packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ export default {
9797
const stateVariables = new WeakSet();
9898
const stableKnownValueCache = new WeakMap();
9999
const functionWithoutCapturedValueCache = new WeakMap();
100-
const useEffectEventVariables = new WeakSet();
101100
function memoizeWithWeakMap(fn, map) {
102101
return function (arg) {
103102
if (map.has(arg)) {
@@ -183,8 +182,6 @@ export default {
183182
// ^^^ true for this reference
184183
// const ref = useRef()
185184
// ^^^ true for this reference
186-
// const onStuff = useEffectEvent(() => {})
187-
// ^^^ true for this reference
188185
// False for everything else.
189186
function isStableKnownHookValue(resolved) {
190187
if (!isArray(resolved.defs)) {
@@ -251,17 +248,6 @@ export default {
251248
if (name === 'useRef' && id.type === 'Identifier') {
252249
// useRef() return value is stable.
253250
return true;
254-
} else if (
255-
isUseEffectEventIdentifier(callee) &&
256-
id.type === 'Identifier'
257-
) {
258-
for (const ref of resolved.references) {
259-
if (ref !== id) {
260-
useEffectEventVariables.add(ref.identifier);
261-
}
262-
}
263-
// useEffectEvent() return value is always unstable.
264-
return true;
265251
} else if (
266252
name === 'useState' ||
267253
name === 'useReducer' ||
@@ -687,26 +673,7 @@ export default {
687673
});
688674
return;
689675
}
690-
if (useEffectEventVariables.has(declaredDependencyNode)) {
691-
reportProblem({
692-
node: declaredDependencyNode,
693-
message:
694-
'Functions returned from `useEffectEvent` must not be included in the dependency array. ' +
695-
`Remove \`${getSource(
696-
declaredDependencyNode,
697-
)}\` from the list.`,
698-
suggest: [
699-
{
700-
desc: `Remove the dependency \`${getSource(
701-
declaredDependencyNode,
702-
)}\``,
703-
fix(fixer) {
704-
return fixer.removeRange(declaredDependencyNode.range);
705-
},
706-
},
707-
],
708-
});
709-
}
676+
710677
// Try to normalize the declared dependency. If we can't then an error
711678
// will be thrown. We will catch that error and report an error.
712679
let declaredDependency;
@@ -1910,13 +1877,6 @@ function isAncestorNodeOf(a, b) {
19101877
return a.range[0] <= b.range[0] && a.range[1] >= b.range[1];
19111878
}
19121879

1913-
function isUseEffectEventIdentifier(node) {
1914-
if (__EXPERIMENTAL__) {
1915-
return node.type === 'Identifier' && node.name === 'useEffectEvent';
1916-
}
1917-
return false;
1918-
}
1919-
19201880
function getUnknownDependenciesMessage(reactiveHookName) {
19211881
return (
19221882
`React Hook ${reactiveHookName} received a function whose dependencies ` +

0 commit comments

Comments
 (0)