Skip to content

Commit

Permalink
fix hot reload issue the right way
Browse files Browse the repository at this point in the history
  • Loading branch information
abailly-akamai committed Jul 15, 2024
1 parent 129cc35 commit c275b5a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 24 deletions.
25 changes: 12 additions & 13 deletions packages/manager/src/dev-tools/dev-tools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import Handyman from '@mui/icons-material/Handyman';
import { QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';

import { handleRoot } from 'src/utilities/rootManager';

import './dev-tools.css';
import { EnvironmentToggleTool } from './EnvironmentToggleTool';
import { FeatureFlagTool } from './FeatureFlagTool';
import { isMSWEnabled } from './ServiceWorkerTool';
import { ServiceWorkerTool } from './ServiceWorkerTool';
import { isMSWEnabled } from './ServiceWorkerTool';

import type { QueryClient } from '@tanstack/react-query';
import type { ApplicationStore } from 'src/store';
Expand Down Expand Up @@ -107,18 +108,16 @@ function install(store: ApplicationStore, queryClient: QueryClient) {
);
}

const devToolsRoot = (() => {
const existingRoot = document.getElementById('dev-tools-root');
if (existingRoot) {
return existingRoot;
}
const newRoot = document.createElement('div');
newRoot.id = 'dev-tools-root';
document.body.appendChild(newRoot);
return newRoot;
})();
const devToolsRoot =
document.getElementById('dev-tools-root') ||
(() => {
const newRoot = document.createElement('div');
newRoot.id = 'dev-tools-root';
document.body.appendChild(newRoot);
return newRoot;
})();

const root = createRoot(devToolsRoot);
const root = handleRoot(devToolsRoot);
root.render(
<Provider store={store}>
<DevTools />
Expand Down
16 changes: 6 additions & 10 deletions packages/manager/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import CssBaseline from '@mui/material/CssBaseline';
import { QueryClientProvider } from '@tanstack/react-query';
// import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider as ReduxStoreProvider } from 'react-redux';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';

Expand All @@ -20,6 +18,7 @@ import { loadDevTools, shouldEnableDevTools } from './dev-tools/load';
import './index.css';
import { LinodeThemeWrapper } from './LinodeThemeWrapper';
import { queryClientFactory } from './queries/base';
import { handleRoot } from './utilities/rootManager';

const queryClient = queryClientFactory('longLived');
const store = storeFactory();
Expand Down Expand Up @@ -80,24 +79,21 @@ const Main = () => {
</Router>
</React.Suspense>
</LinodeThemeWrapper>
{/* <ReactQueryDevtools
initialIsOpen={false}
toggleButtonProps={{ style: { marginLeft: '3em' } }}
/>*/}
</QueryClientProvider>
</ReduxStoreProvider>
);
};

async function loadApp() {
if (shouldEnableDevTools) {
// If devtools are enabled, load them before we load the main app.
// This ensures the MSW is setup before we start making API calls.
await loadDevTools(store, queryClient);
}

const container = document.getElementById('root');
const root = createRoot(container!);
root.render(<Main />);
if (container) {
const root = handleRoot(container);
root.render(<Main />);
}
}

loadApp();
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const getPlacementGroups = (mockContext: MockContext) => [

return makePaginatedResponse(pageSlice, pageNumber, totalPages);
}),

///
http.get(
'*/v4/placement/groups/:id',
({ params }): StrictResponse<APIErrorResponse | PlacementGroup> => {
Expand Down
38 changes: 38 additions & 0 deletions packages/manager/src/utilities/rootManager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createRoot } from 'react-dom/client';

import { handleRoot, rootInstances } from './rootManager';

vi.mock('react-dom/client', () => ({
createRoot: vi.fn().mockImplementation((container) => ({
_internalRoot: container, // Mock implementation detail
render: vi.fn(),
})),
}));

describe('handleRoot', () => {
beforeEach(() => {
vi.clearAllMocks();
rootInstances.clear();
});

it('should create a new root for a new container', () => {
const container = document.createElement('div');
const root = handleRoot(container);

expect(createRoot).toHaveBeenCalledWith(container);
expect(rootInstances.get(container)).toBe(root);
expect(createRoot).toHaveBeenCalledTimes(1);
});

it('should return the existing root for an existing container', () => {
const container = document.createElement('div');
// Call handleRoot twice with the same container
const firstCallRoot = handleRoot(container);
const secondCallRoot = handleRoot(container);

// createRoot should only have been called once
expect(createRoot).toHaveBeenCalledTimes(1);
expect(firstCallRoot).toBe(secondCallRoot);
expect(rootInstances.size).toBe(1);
});
});
16 changes: 16 additions & 0 deletions packages/manager/src/utilities/rootManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createRoot } from 'react-dom/client';

import type { Root } from 'react-dom/client';

export const rootInstances = new Map<HTMLElement, Root>();

export function handleRoot(container: HTMLElement): Root {
let root = rootInstances.get(container);

if (!root) {
root = createRoot(container);
rootInstances.set(container, root);
}

return root;
}

0 comments on commit c275b5a

Please sign in to comment.