Don't crash for deeply nested Hooks
Dan Abramov committed
Apr 4, 2019 at 19:28 UTC
8478a526e646fdeeaf6e254bb73b90571f2f32b9
3 files changed
+39
shells/dev/app/InspectableElements/CustomHooks.js
+10
@@ -32,6 +32,13 @@ function useCustomObject() {
32
return useState(123);
33
}
34
35
+function useVeryDeeplyNestedHook(i) {
36
+ useDebugValue(i);
37
+ if (i > 0) {
38
+ useVeryDeeplyNestedHook(i - 1);
39
+ }
40
+}
41
+
42
function FunctionWithHooks(props: any, ref: React$Ref<any>) {
43
const [count, updateCount] = useState(0);
44
@@ -53,6 +60,9 @@ function FunctionWithHooks(props: any, ref: React$Ref<any>) {
60
// Tests nested custom hooks
61
useNestedOuterHook();
62
63
+ // Verify deep nesting doesn't break
64
+ useVeryDeeplyNestedHook(50);
65
+
66
return <button onClick={onClick}>Count: {debouncedCount}</button>;
67
}
68
const MemoWithHooks = memo(FunctionWithHooks);
shells/dev/app/InspectableElements/NestedProps.js
+23
@@ -23,6 +23,29 @@ export default function ObjectProps() {
23
array={['first', 'second', 'third']}
24
objectInArray={[object]}
25
arrayInObject={{ array: ['first', 'second', 'third'] }}
26
+ deepObject={{
27
+ // Known limitation: we won't go deeper than several levels.
28
+ // In the future, we might offer a way to request deeper access on demand.
29
+ a: {
30
+ b: {
31
+ c: {
32
+ d: {
33
+ e: {
34
+ f: {
35
+ g: {
36
+ h: {
37
+ i: {
38
+ j: 10,
39
+ },
40
+ },
41
+ },
42
+ },
43
+ },
44
+ },
45
+ },
46
+ },
47
+ },
48
+ }}
49
/>
50
);
51
}
src/devtools/views/Components/HooksTree.js
+6
@@ -9,6 +9,7 @@ import EditableValue from './EditableValue';
9
import KeyValue from './KeyValue';
10
import { serializeHooksForCopy } from '../utils';
11
import styles from './HooksTree.css';
12
+import { meta } from '../../../hydration';
13
14
import type { HooksNode, HooksTree } from 'src/backend/types';
15
@@ -71,6 +72,11 @@ type HookViewProps = {|
72
73
function HookView({ canEditHooks, hook, id, path = [] }: HookViewProps) {
74
const { name, id: hookID, isStateEditable, subHooks, value } = hook;
75
+ if (hook.hasOwnProperty(meta.inspected)) {
76
+ // This Hook is too deep and hasn't been hydrated.
77
+ // TODO: show UI to load its data.
78
+ return null;
79
+ }
80
81
const bridge = useContext(BridgeContext);
82
const store = useContext(StoreContext);