File tree Expand file tree Collapse file tree 2 files changed +43
-9
lines changed
packages/eslint-plugin-react-hooks Expand file tree Collapse file tree 2 files changed +43
-9
lines changed Original file line number Diff line number Diff line change @@ -407,7 +407,7 @@ const tests = {
407407 }
408408 ` ,
409409 `
410- // Valid because render-hooks acts as a component boundary
410+ // Valid because Hooks component acts as a component boundary
411411 function App(props) {
412412 return props.isOpen
413413 ? <Hooks>
@@ -416,6 +416,14 @@ const tests = {
416416 : null;
417417 }
418418 ` ,
419+ `
420+ // Valid because hooks function acts as a component boundary
421+ function App(props) {
422+ return props.isOpen
423+ ? hooks(() => <Modal close={useCallback(() => props.setIsOpen(false), [props.setIsOpen])} />)
424+ : null;
425+ }
426+ ` ,
419427 ] ,
420428 invalid : [
421429 {
@@ -968,7 +976,7 @@ const tests = {
968976 } ,
969977 {
970978 code : `
971- // Invalid because rule of hooks still need to be adhered to within render-hooks
979+ // Invalid because rule of hooks still need to be adhered to within Hooks component
972980 function App(props) {
973981 return props.isOpen
974982 ? <Hooks>
@@ -979,8 +987,21 @@ const tests = {
979987 : null;
980988 }
981989 ` ,
982- errors : [ conditionalError ( 'useCallback' ) ]
983- }
990+ errors : [ conditionalError ( 'useCallback' ) ] ,
991+ } ,
992+ {
993+ code : `
994+ // Invalid because rule of hooks still need to be adhered to within hooks function
995+ function App(props) {
996+ return props.isOpen
997+ ? hooks(() => {
998+ return <Modal close={props.setIsOpen ? useCallback(() => props.setIsOpen(false), [props.setIsOpen]) : undefined} />;
999+ })
1000+ : null;
1001+ }
1002+ ` ,
1003+ errors : [ conditionalError ( 'useCallback' ) ] ,
1004+ } ,
9841005 ] ,
9851006} ;
9861007
Original file line number Diff line number Diff line change @@ -106,11 +106,22 @@ function isInsideComponentOrHook(node) {
106106}
107107
108108function isDirectlyInsideRenderHooks ( node ) {
109- return node . parent &&
110- node . parent . type === 'JSXExpressionContainer' &&
111- node . parent . parent &&
112- node . parent . parent . type === 'JSXElement' &&
109+ if ( ! node . parent ) {
110+ return false ;
111+ }
112+
113+ const isDirectlyInsideHooksComponent =
114+ node . parent . type === 'JSXExpressionContainer' &&
115+ node . parent . parent &&
116+ node . parent . parent . type === 'JSXElement' &&
113117 node . parent . parent . openingElement . name . name === 'Hooks' ;
118+ const isDirectlyInsideHooksFunction =
119+ node . parent . type === 'CallExpression' &&
120+ node . parent . callee &&
121+ node . parent . callee . type === 'Identifier' &&
122+ node . parent . callee . name === 'hooks' ;
123+
124+ return isDirectlyInsideHooksComponent || isDirectlyInsideHooksFunction ;
114125}
115126
116127export default {
@@ -360,7 +371,9 @@ export default {
360371 const isDirectlyInsideComponentOrHook = codePathFunctionName
361372 ? isComponentName ( codePathFunctionName ) ||
362373 isHook ( codePathFunctionName )
363- : isForwardRefCallback ( codePathNode ) || isMemoCallback ( codePathNode ) || isDirectlyInsideRenderHooks ( codePathNode ) ;
374+ : isForwardRefCallback ( codePathNode ) ||
375+ isMemoCallback ( codePathNode ) ||
376+ isDirectlyInsideRenderHooks ( codePathNode ) ;
364377
365378 // Compute the earliest finalizer level using information from the
366379 // cache. We expect all reachable final segments to have a cache entry
You can’t perform that action at this time.
0 commit comments