diff --git a/static/app/components/events/eventReplay/index.tsx b/static/app/components/events/eventReplay/index.tsx index e30afc944f1879..6325091dbb9c8a 100644 --- a/static/app/components/events/eventReplay/index.tsx +++ b/static/app/components/events/eventReplay/index.tsx @@ -1,4 +1,4 @@ -import {Fragment, useCallback} from 'react'; +import {Fragment, lazy} from 'react'; import ReactLazyLoad from 'react-lazyload'; import styled from '@emotion/styled'; @@ -36,6 +36,10 @@ export const REPLAY_CLIP_OFFSETS = { durationBeforeMs: 5_000, }; +const ReplayOnboardingPanel = lazy(() => import('./replayInlineOnboardingPanel')); +const ReplayPreview = lazy(() => import('./replayPreview')); +const ReplayClipPreview = lazy(() => import('./replayClipPreview')); + function EventReplayContent({ event, group, @@ -46,13 +50,6 @@ function EventReplayContent({ const router = useRouter(); const {getReplayCountForIssue} = useReplayCountForIssues(); - const replayOnboardingPanel = useCallback( - () => import('./replayInlineOnboardingPanel'), - [] - ); - const replayPreview = useCallback(() => import('./replayPreview'), []); - const replayClipPreview = useCallback(() => import('./replayClipPreview'), []); - const hasReplayClipFeature = organization.features.includes( 'issue-details-inline-replay-viewer' ); @@ -69,7 +66,7 @@ function EventReplayContent({ return ( @@ -148,12 +145,12 @@ function EventReplayContent({ {hasReplayClipFeature ? ( ) : ( - + )} diff --git a/static/app/components/lazyLoad.spec.tsx b/static/app/components/lazyLoad.spec.tsx index 5102597422b806..6915d87d407f3f 100644 --- a/static/app/components/lazyLoad.spec.tsx +++ b/static/app/components/lazyLoad.spec.tsx @@ -1,3 +1,5 @@ +import {lazy} from 'react'; + import {render, screen} from 'sentry-test/reactTestingLibrary'; import LazyLoad from 'sentry/components/lazyLoad'; @@ -15,7 +17,6 @@ function BarComponent({}: TestProps) { } type ResolvedComponent = {default: React.ComponentType}; -type GetComponent = () => Promise; describe('LazyLoad', function () { afterEach(() => { @@ -25,7 +26,7 @@ describe('LazyLoad', function () { it('renders with a loading indicator when promise is not resolved yet', function () { const importTest = new Promise(() => {}); const getComponent = () => importTest; - render(); + render(); // Should be loading expect(screen.getByTestId('loading-indicator')).toBeInTheDocument(); @@ -37,7 +38,7 @@ describe('LazyLoad', function () { doResolve = resolve; }); - render( importFoo} />); + render( importFoo)} />); // Should be loading expect(screen.getByTestId('loading-indicator')).toBeInTheDocument(); @@ -58,7 +59,7 @@ describe('LazyLoad', function () { ); try { - render(); + render(); } catch (err) { // ignore } @@ -78,7 +79,7 @@ describe('LazyLoad', function () { }); // First render Foo - const {rerender} = render( importFoo} />); + const {rerender} = render( importFoo)} />); expect(screen.getByTestId('loading-indicator')).toBeInTheDocument(); // resolve with foo @@ -90,7 +91,7 @@ describe('LazyLoad', function () { doResolve = resolve; }); - rerender( importBar} />); + rerender( importBar)} />); expect(screen.getByTestId('loading-indicator')).toBeInTheDocument(); // resolve with bar @@ -98,14 +99,13 @@ describe('LazyLoad', function () { expect(await screen.findByText('my bar component')).toBeInTheDocument(); // Update component prop to a mock to make sure it isn't re-called - const getComponent2: GetComponent = jest.fn( - () => new Promise(() => {}) - ); - rerender(); + const getComponent2 = jest.fn(() => new Promise(() => {})); + const LazyGet = lazy(getComponent2); + rerender(); expect(getComponent2).toHaveBeenCalledTimes(1); // Does not refetch on other prop changes - rerender(); + rerender(); expect(getComponent2).toHaveBeenCalledTimes(1); }); }); diff --git a/static/app/components/lazyLoad.tsx b/static/app/components/lazyLoad.tsx index 3ffc23fb8518b4..84f0a41ab27e01 100644 --- a/static/app/components/lazyLoad.tsx +++ b/static/app/components/lazyLoad.tsx @@ -1,5 +1,5 @@ import type {ErrorInfo} from 'react'; -import {Component, lazy, Suspense, useMemo} from 'react'; +import {Component, Suspense} from 'react'; import styled from '@emotion/styled'; import * as Sentry from '@sentry/react'; @@ -7,23 +7,13 @@ import LoadingError from 'sentry/components/loadingError'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import {t} from 'sentry/locale'; import {isWebpackChunkLoadingError} from 'sentry/utils'; -import retryableImport from 'sentry/utils/retryableImport'; - -type PromisedImport = Promise<{default: C}>; - -type ComponentType = React.ComponentType; - -type Props = React.ComponentProps & { - /** - * Wrap the component with lazy() before passing it to LazyLoad. - */ - LazyComponent?: React.LazyExoticComponent; +type Props> = React.ComponentProps & { /** - * Accepts a function to trigger the import resolution of the component. - * @deprecated Use `LazyComponent` instead and keep lazy() calls out of the render path. + * Wrap the component with `lazy()` before passing it to LazyLoad. + * This should be declared outside of the render funciton. */ - component?: () => PromisedImport; + LazyComponent: C; /** * Override the default fallback component. @@ -42,20 +32,11 @@ type Props = React.ComponentProps & { * * */ -function LazyLoad({ - component, - loadingFallback, +function LazyLoad>({ LazyComponent, + loadingFallback, ...props }: Props) { - const LazyLoadedComponent = useMemo(() => { - if (LazyComponent) { - return LazyComponent; - } - - return lazy(() => retryableImport(component)); - }, [component, LazyComponent]); - return ( ({ ) } > - )} /> + {/* Props are strongly typed when passed in, but seem to conflict with LazyExoticComponent */} + ); diff --git a/static/app/routes.tsx b/static/app/routes.tsx index 10e424d974fdd3..bdee14bc21158a 100644 --- a/static/app/routes.tsx +++ b/static/app/routes.tsx @@ -28,7 +28,10 @@ import {IndexRoute, Route} from './components/route'; const hook = (name: HookName) => HookStore.get(name).map(cb => cb()); -const SafeLazyLoad = errorHandler(LazyLoad); +// LazyExoticComponent Props get crazy when wrapped in an additional layer +const SafeLazyLoad = errorHandler(LazyLoad) as unknown as React.ComponentType< + typeof LazyLoad +>; // NOTE: makeLazyloadComponent is exported for use in the sentry.io (getsentry) // pirvate routing tree.