Repository: facebook/react
Pull request: [DevTools] Don't call Hooks conditionally


Changed files:
filename: packages/react-devtools-shared/src/devtools/views/Profiler/SidebarEventInfo.js
patch: @@ -8,6 +8,7 @@
  */
 
 import type {SchedulingEvent} from 'react-devtools-timeline/src/types';
+import type {ReactFunctionLocation} from 'shared/ReactTypes';
 
 import * as React from 'react';
 import Button from '../Button';
@@ -27,6 +28,28 @@ import styles from './SidebarEventInfo.css';
 
 export type Props = {};
 
+type FunctionLocationProps = {
+  location: ReactFunctionLocation,
+  displayName: string,
+};
+function FunctionLocation({location, displayName}: FunctionLocationProps) {
+  // TODO: We should support symbolication here as well, but
+  // symbolicating the whole stack can be expensive
+  const [canViewSource, viewSource] = useOpenResource(location, null);
+  return (
+    <li>
+      <Button
+        className={
+          canViewSource ? styles.ClickableSource : styles.UnclickableSource
+        }
+        disabled={!canViewSource}
+        onClick={viewSource}>
+        {displayName}
+      </Button>
+    </li>
+  );
+}
+
 type SchedulingEventProps = {
   eventInfo: SchedulingEvent,
 };
@@ -74,25 +97,12 @@ function SchedulingEventInfo({eventInfo}: SchedulingEventProps) {
                       );
                     }
 
-                    // TODO: We should support symbolication here as well, but
-                    // symbolicating the whole stack can be expensive
-                    const [canViewSource, viewSource] = useOpenResource(
-                      location,
-                      null,
-                    );
                     return (
-                      <li key={index}>
-                        <Button
-                          className={
-                            canViewSource
-                              ? styles.ClickableSource
-                              : styles.UnclickableSource
-                          }
-                          disabled={!canViewSource}
-                          onClick={viewSource}>
-                          {displayName}
-                        </Button>
-                      </li>
+                      <FunctionLocation
+                        key={index}
+                        displayName={displayName}
+                        location={location}
+                      />
                     );
                   },
                 )}

filename: packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTimeline.js
patch: @@ -39,28 +39,6 @@ function SuspenseTimelineInput() {
   const min = 0;
   const max = timeline.length > 0 ? timeline.length - 1 : 0;
 
-  if (rootID === null) {
-    return (
-      <div className={styles.SuspenseTimelineInput}>No root selected.</div>
-    );
-  }
-
-  if (!store.supportsTogglingSuspense(rootID)) {
-    return (
-      <div className={styles.SuspenseTimelineInput}>
-        Can't step through Suspense in production apps.
-      </div>
-    );
-  }
-
-  if (timeline.length === 0) {
-    return (
-      <div className={styles.SuspenseTimelineInput}>
-        Root contains no Suspense nodes.
-      </div>
-    );
-  }
-
   function switchSuspenseNode(nextTimelineIndex: number) {
     const nextSelectedSuspenseID = timeline[nextTimelineIndex];
     highlightHostInstance(nextSelectedSuspenseID);
@@ -175,6 +153,28 @@ function SuspenseTimelineInput() {
     };
   }, [playing]);
 
+  if (rootID === null) {
+    return (
+      <div className={styles.SuspenseTimelineInput}>No root selected.</div>
+    );
+  }
+
+  if (!store.supportsTogglingSuspense(rootID)) {
+    return (
+      <div className={styles.SuspenseTimelineInput}>
+        Can't step through Suspense in production apps.
+      </div>
+    );
+  }
+
+  if (timeline.length === 0) {
+    return (
+      <div className={styles.SuspenseTimelineInput}>
+        Root contains no Suspense nodes.
+      </div>
+    );
+  }
+
   return (
     <>
       <Button