@@ -313,7 +313,7 @@ const tests = {
313
313
} ,
314
314
{
315
315
code : `
316
- function MyComponent({ maybeRef2 }) {
316
+ function MyComponent({ maybeRef2, foo }) {
317
317
const definitelyRef1 = useRef();
318
318
const definitelyRef2 = useRef();
319
319
const maybeRef1 = useSomeOtherRefyThing();
@@ -323,8 +323,8 @@ const tests = {
323
323
const [state4, dispatch2] = React.useReducer();
324
324
const [state5, maybeSetState] = useFunnyState();
325
325
const [state6, maybeDispatch] = useFunnyReducer();
326
- function mySetState() {}
327
- function myDispatch() {}
326
+ const mySetState = useCallback(() => {}, []);
327
+ let myDispatch = useCallback(() => {}, []);
328
328
329
329
useEffect(() => {
330
330
// Known to be static
@@ -380,8 +380,8 @@ const tests = {
380
380
const [state5, maybeSetState] = useFunnyState();
381
381
const [state6, maybeDispatch] = useFunnyReducer();
382
382
383
- function mySetState() {}
384
- function myDispatch() {}
383
+ const mySetState = useCallback(() => {}, []);
384
+ let myDispatch = useCallback(() => {}, []);
385
385
386
386
useEffect(() => {
387
387
// Known to be static
@@ -662,30 +662,6 @@ const tests = {
662
662
}
663
663
` ,
664
664
} ,
665
- {
666
- code : `
667
- function MyComponent(props) {
668
- function handleNext1() {
669
- console.log('hello');
670
- }
671
- const handleNext2 = () => {
672
- console.log('hello');
673
- };
674
- let handleNext3 = function() {
675
- console.log('hello');
676
- };
677
- useEffect(() => {
678
- return Store.subscribe(handleNext1);
679
- }, [handleNext1]);
680
- useLayoutEffect(() => {
681
- return Store.subscribe(handleNext2);
682
- }, [handleNext2]);
683
- useMemo(() => {
684
- return Store.subscribe(handleNext3);
685
- }, [handleNext3]);
686
- }
687
- ` ,
688
- } ,
689
665
{
690
666
// Declaring handleNext is optional because
691
667
// it doesn't use anything in the function scope.
@@ -3313,6 +3289,139 @@ const tests = {
3313
3289
'Either include it or remove the dependency array.' ,
3314
3290
] ,
3315
3291
} ,
3292
+ {
3293
+ // Even if the function only references static values,
3294
+ // once you specify it in deps, it will invalidate them.
3295
+ code : `
3296
+ function MyComponent(props) {
3297
+ let [, setState] = useState();
3298
+
3299
+ function handleNext(value) {
3300
+ setState(value);
3301
+ }
3302
+
3303
+ useEffect(() => {
3304
+ return Store.subscribe(handleNext);
3305
+ }, [handleNext]);
3306
+ }
3307
+ ` ,
3308
+ output : `
3309
+ function MyComponent(props) {
3310
+ let [, setState] = useState();
3311
+
3312
+ const handleNext = useCallback(function (value) {
3313
+ setState(value);
3314
+ }, []);
3315
+
3316
+ useEffect(() => {
3317
+ return Store.subscribe(handleNext);
3318
+ }, [handleNext]);
3319
+ }
3320
+ ` ,
3321
+ errors : [
3322
+ `The 'handleNext' function is used in a React Hook dependencies array but ` +
3323
+ `its identity changes on every render. As a result, the dependency array serves no ` +
3324
+ `purpose. To fix this, try wrapping 'handleNext' into a useCallback() Hook.` ,
3325
+ ] ,
3326
+ } ,
3327
+ {
3328
+ code : `
3329
+ function MyComponent(props) {
3330
+ function handleNext1() {
3331
+ console.log('hello');
3332
+ }
3333
+ const handleNext2 = () => {
3334
+ console.log('hello');
3335
+ };
3336
+ let handleNext3 = function() {
3337
+ console.log('hello');
3338
+ };
3339
+ useEffect(() => {
3340
+ return Store.subscribe(handleNext1);
3341
+ }, [handleNext1]);
3342
+ useLayoutEffect(() => {
3343
+ return Store.subscribe(handleNext2);
3344
+ }, [handleNext2]);
3345
+ useMemo(() => {
3346
+ return Store.subscribe(handleNext3);
3347
+ }, [handleNext3]);
3348
+ }
3349
+ ` ,
3350
+ output : `
3351
+ function MyComponent(props) {
3352
+ const handleNext1 = useCallback(function () {
3353
+ console.log('hello');
3354
+ }, []);
3355
+ const handleNext2 = useCallback(() => {
3356
+ console.log('hello');
3357
+ }, []);
3358
+ let handleNext3 = useCallback(function() {
3359
+ console.log('hello');
3360
+ }, []);
3361
+ useEffect(() => {
3362
+ return Store.subscribe(handleNext1);
3363
+ }, [handleNext1]);
3364
+ useLayoutEffect(() => {
3365
+ return Store.subscribe(handleNext2);
3366
+ }, [handleNext2]);
3367
+ useMemo(() => {
3368
+ return Store.subscribe(handleNext3);
3369
+ }, [handleNext3]);
3370
+ }
3371
+ ` ,
3372
+ errors : [
3373
+ `The 'handleNext1' function is used in a React Hook dependencies array but ` +
3374
+ `its identity changes on every render. As a result, the dependency array serves no ` +
3375
+ `purpose. To fix this, try wrapping 'handleNext1' into a useCallback() Hook.` ,
3376
+ `The 'handleNext2' function is used in a React Hook dependencies array but ` +
3377
+ `its identity changes on every render. As a result, the dependency array serves no ` +
3378
+ `purpose. To fix this, try wrapping 'handleNext2' into a useCallback() Hook.` ,
3379
+ `The 'handleNext3' function is used in a React Hook dependencies array but ` +
3380
+ `its identity changes on every render. As a result, the dependency array serves no ` +
3381
+ `purpose. To fix this, try wrapping 'handleNext3' into a useCallback() Hook.` ,
3382
+ ] ,
3383
+ } ,
3384
+ {
3385
+ code : `
3386
+ function MyComponent(props) {
3387
+ let [, setState] = useState();
3388
+ let taint = props.foo;
3389
+
3390
+ function handleNext(value) {
3391
+ let value2 = value * taint;
3392
+ setState(value2);
3393
+ console.log('hello');
3394
+ }
3395
+
3396
+ useEffect(() => {
3397
+ return Store.subscribe(handleNext);
3398
+ }, [handleNext]);
3399
+ }
3400
+ ` ,
3401
+ // TODO: can we include autofix for useCallback right away
3402
+ // instead of emitting an empty array by default?
3403
+ output : `
3404
+ function MyComponent(props) {
3405
+ let [, setState] = useState();
3406
+ let taint = props.foo;
3407
+
3408
+ const handleNext = useCallback(function (value) {
3409
+ let value2 = value * taint;
3410
+ setState(value2);
3411
+ console.log('hello');
3412
+ }, []);
3413
+
3414
+ useEffect(() => {
3415
+ return Store.subscribe(handleNext);
3416
+ }, [handleNext]);
3417
+ }
3418
+ ` ,
3419
+ errors : [
3420
+ `The 'handleNext' function is used in a React Hook dependencies array but ` +
3421
+ `its identity changes on every render. As a result, the dependency array serves no ` +
3422
+ `purpose. To fix this, try wrapping 'handleNext' into a useCallback() Hook.` ,
3423
+ ] ,
3424
+ } ,
3316
3425
{
3317
3426
code : `
3318
3427
function Counter() {
0 commit comments