Fix hooks warnings identified by prerelease version of react-hooks ESLint plugin
Brian Vaughn committed
Feb 19, 2019 at 13:15 UTC
bec073365d14aba07ff98a589ab52301761e7a72
8 files changed
+72
-38
shells/dev/app/ToDoList/List.js
+1
-1
@@ -34,7 +34,7 @@ export default function List(props: Props) {
34
setUID(uid + 1);
35
setNewItemText('');
36
}
37
- }, [newItemText]);
37
+ }, [newItemText, items, uid]);
38
39
const handleKeyPress = useCallback(
40
event => {
src/devtools/views/Element.js
+23
-10
@@ -25,22 +25,35 @@ export default function ElementView({ index, style }: Props) {
25
26
const element = getElementAtIndex(index);
27
28
- if (element == null) {
29
- console.warn(`<ElementView> Could not find element at index ${index}`);
30
- return null;
31
- }
32
-
33
- const { depth, displayName, id, key, type } = ((element: any): Element);
28
+ const id = element === null ? null : element.id;
29
35
- const handleDoubleClick = useCallback(() => selectOwner(id), [id]);
30
+ const handleDoubleClick = useCallback(() => {
31
+ if (id !== null) {
32
+ selectOwner(id);
33
+ }
34
+ }, [id, selectOwner]);
35
36
// TODO Add click and key handlers for toggling element open/close state.
37
38
const handleClick = useCallback(
40
- ({ metaKey }) => selectElementByID(metaKey ? null : id),
41
- [id]
39
+ ({ metaKey }) => {
40
+ if (id !== null) {
41
+ selectElementByID(metaKey ? null : id);
42
+ }
43
+ },
44
+ [id, selectElementByID]
45
);
46
47
+ // Handle elements that are removed from the tree while an async render is in progress.
48
+ if (element == null) {
49
+ console.warn(`<ElementView> Could not find element at index ${index}`);
50
+
51
+ // This return needs to happen after hooks, since hooks can't be conditional.
52
+ return null;
53
+ }
54
+
55
+ const { depth, displayName, key, type } = ((element: any): Element);
56
+
57
const isSelected = selectedElementID === id;
58
const showDollarR =
59
isSelected && (type === ElementTypeClass || type === ElementTypeFunction);
@@ -58,7 +71,7 @@ export default function ElementView({ index, style }: Props) {
71
}}
72
>
73
<span className={styles.Component}>
61
- <DisplayName displayName={displayName} id={id} />
74
+ <DisplayName displayName={displayName} id={((id: any): number)} />
75
{key && (
76
<Fragment>
77
<span className={styles.AttributeName}>key</span>=
src/devtools/views/InspectedElementTree.js
+1
-1
@@ -183,7 +183,7 @@ function EditableValue({
183
setEditableValue(target.value);
184
}
185
},
186
- [dataType, setEditableValue]
186
+ [dataType, overrideValueFn, path]
187
);
188
189
const handleKeyPress = useCallback(
src/devtools/views/SelectedElement.js
+6
-3
@@ -43,7 +43,7 @@ export default function SelectedElement(_: Props) {
43
});
44
}
45
}
46
- }, [bridge, selectedElementID, store]);
46
+ }, [bridge, element, selectedElementID, store]);
47
48
// TODO Make "view source" button work
49
@@ -176,7 +176,10 @@ function InspectedElementView({
176
function OwnerView({ displayName, id }: { displayName: string, id: number }) {
177
const { selectElementByID } = useContext(TreeContext);
178
179
- const handleClick = useCallback(() => selectElementByID(id), [id]);
179
+ const handleClick = useCallback(() => selectElementByID(id), [
180
+ id,
181
+ selectElementByID,
182
+ ]);
183
184
return (
185
<div
@@ -260,7 +263,7 @@ function useInspectedElement(id: number | null): InspectedElement | null {
263
264
bridge.removeListener('inspectedElement', onInspectedElement);
265
};
263
- }, [id]);
266
+ }, [bridge, id, idRef, store]);
267
268
return inspectedElement;
269
}
src/devtools/views/SettingsContext.js
+9
-2
@@ -76,7 +76,7 @@ function SettingsContextController({ browserTheme, children }: Props) {
76
default:
77
throw Error(`Unsupported theme value "${theme}"`);
78
}
79
- }, [theme]);
79
+ }, [browserTheme, theme]);
80
81
const value = useMemo(
82
() => ({
@@ -89,7 +89,14 @@ function SettingsContextController({ browserTheme, children }: Props) {
89
? compactLineHeight
90
: comfortableLineHeight,
91
}),
92
- [displayDensity, setDisplayDensity, theme, setTheme]
92
+ [
93
+ comfortableLineHeight,
94
+ compactLineHeight,
95
+ displayDensity,
96
+ setDisplayDensity,
97
+ setTheme,
98
+ theme,
99
+ ]
100
);
101
102
return (
src/devtools/views/Tree.js
+1
-5
@@ -63,11 +63,7 @@ export default function Tree(props: Props) {
63
return () => {
64
window.removeEventListener('keydown', handleKeyDown);
65
};
66
- }, [
67
- selectedElementIndex,
68
- selectNextElementInTree,
69
- selectPreviousElementInTree,
70
- ]);
66
+ }, [selectNextElementInTree, selectPreviousElementInTree]);
67
68
// Let react-window know to re-render any time the underlying tree data changes.
69
// This includes the owner context, since it controls a filtered view of the tree.
src/devtools/views/TreeContext.js
+14
-2
@@ -595,7 +595,19 @@ function TreeContextController({ children }: {| children: React$Node |}) {
595
resetOwnerStack,
596
selectOwner,
597
}),
598
- [state]
598
+ [
599
+ getElementAtIndex,
600
+ goToNextSearchResult,
601
+ goToPreviousSearchResult,
602
+ resetOwnerStack,
603
+ selectElementAtIndex,
604
+ selectElementByID,
605
+ selectNextElementInTree,
606
+ selectOwner,
607
+ selectPreviousElementInTree,
608
+ setSearchText,
609
+ state,
610
+ ]
611
);
612
613
// Listen for host element selections.
@@ -632,7 +644,7 @@ function TreeContextController({ children }: {| children: React$Node |}) {
644
store.addListener('mutated', handleStoreMutated);
645
646
return () => store.removeListener('mutated', handleStoreMutated);
635
- }, [dispatch, store]);
647
+ }, [dispatch, initialRevision, store]);
648
649
return <TreeContext.Provider value={value}>{children}</TreeContext.Provider>;
650
}
src/devtools/views/hooks.js
+17
-14
@@ -1,13 +1,13 @@
1
// @flow
2
3
-import { useLayoutEffect, useState } from 'react';
3
+import { useCallback, useLayoutEffect, useState } from 'react';
4
5
// Forked from https://usehooks.com/useLocalStorage/
6
export function useLocalStorage<T>(
7
key: string,
8
initialValue: T
9
): [T, (value: T | (() => T)) => void] {
10
- const getValueFromLocalStorage = () => {
10
+ const getValueFromLocalStorage = useCallback(() => {
11
try {
12
const item = window.localStorage.getItem(key);
13
return item ? JSON.parse(item) : initialValue;
@@ -15,20 +15,23 @@ export function useLocalStorage<T>(
15
console.log(error);
16
return initialValue;
17
}
18
- };
18
+ }, [initialValue, key]);
19
20
const [storedValue, setStoredValue] = useState(getValueFromLocalStorage);
21
22
- const setValue = value => {
23
- try {
24
- const valueToStore =
25
- value instanceof Function ? value(storedValue) : value;
26
- setStoredValue(valueToStore);
27
- window.localStorage.setItem(key, JSON.stringify(valueToStore));
28
- } catch (error) {
29
- console.log(error);
30
- }
31
- };
22
+ const setValue = useCallback(
23
+ value => {
24
+ try {
25
+ const valueToStore =
26
+ value instanceof Function ? value(storedValue) : value;
27
+ setStoredValue(valueToStore);
28
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
29
+ } catch (error) {
30
+ console.log(error);
31
+ }
32
+ },
33
+ [key, storedValue]
34
+ );
35
36
// Listen for changes to this local storage value made from other windows.
37
// This enables the e.g. "⚛️ Elements" tab to update in response to changes from "⚛️ Settings".
@@ -45,7 +48,7 @@ export function useLocalStorage<T>(
48
return () => {
49
window.removeEventListener('storage', onStorage);
50
};
48
- }, [key, storedValue]);
51
+ }, [getValueFromLocalStorage, key, storedValue, setValue]);
52
53
return [storedValue, setValue];
54
}