@samitouri / QOS-React / commits / 8478a526e6

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);