diff --git a/packages/app/package.json b/packages/app/package.json
index 8bfd6859db..5af418f98e 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -23,7 +23,7 @@
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-hot-loader": "^4.12.21",
- "react-router-dom": "^5.2.0",
+ "react-router-dom": "6.0.0-alpha.5",
"react-use": "^14.2.0",
"zen-observable": "^0.8.15"
},
@@ -35,7 +35,6 @@
"@types/jest": "^25.2.2",
"@types/jquery": "^3.3.34",
"@types/node": "^12.0.0",
- "@types/react-router-dom": "^5.1.3",
"@types/zen-observable": "^0.8.0",
"cross-env": "^7.0.0",
"cypress": "^4.2.0",
diff --git a/packages/cli/templates/default-app/packages/app/package.json.hbs b/packages/cli/templates/default-app/packages/app/package.json.hbs
index 2c35dee754..346e09a76a 100644
--- a/packages/cli/templates/default-app/packages/app/package.json.hbs
+++ b/packages/cli/templates/default-app/packages/app/package.json.hbs
@@ -12,7 +12,7 @@
"plugin-welcome": "0.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
- "react-router-dom": "^5.2.0",
+ "react-router-dom": "6.0.0-alpha.5",
"react-use": "^14.2.0"
},
"devDependencies": {
@@ -21,7 +21,6 @@
"@testing-library/user-event": "^10.2.4",
"@types/jest": "^25.2.2",
"@types/node": "^12.0.0",
- "@types/react-router-dom": "^5.1.3",
"@types/testing-library__jest-dom": "^5.0.4",
"cross-env": "^7.0.0",
"cypress": "^4.2.0",
diff --git a/packages/cli/templates/default-app/plugins/welcome/package.json.hbs b/packages/cli/templates/default-app/plugins/welcome/package.json.hbs
index 0bc8fd3d2f..c590b68324 100644
--- a/packages/cli/templates/default-app/plugins/welcome/package.json.hbs
+++ b/packages/cli/templates/default-app/plugins/welcome/package.json.hbs
@@ -27,7 +27,7 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-use": "^14.2.0",
- "react-router-dom": "^5.2.0"
+ "react-router-dom": "6.0.0-alpha.5"
},
"devDependencies": {
"@backstage/cli": "^{{version}}",
diff --git a/packages/core-api/package.json b/packages/core-api/package.json
index f08b03a77e..d64378943f 100644
--- a/packages/core-api/package.json
+++ b/packages/core-api/package.json
@@ -37,7 +37,7 @@
"@types/react": "^16.9",
"prop-types": "^15.7.2",
"react": "^16.12.0",
- "react-router-dom": "^5.2.0",
+ "react-router-dom": "6.0.0-alpha.5",
"react-use": "^14.2.0",
"zen-observable": "^0.8.15"
},
diff --git a/packages/core-api/src/app/App.tsx b/packages/core-api/src/app/App.tsx
index 972acbd8ea..d7920e6bbd 100644
--- a/packages/core-api/src/app/App.tsx
+++ b/packages/core-api/src/app/App.tsx
@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
import React, { ComponentType, FC, useMemo } from 'react';
-import { Route, Switch, Redirect } from 'react-router-dom';
+import { Route, Routes, Navigate } from 'react-router-dom';
import { AppContextProvider } from './AppContext';
import { BackstageApp, AppComponents, AppConfigLoader, Apis } from './types';
import { BackstagePlugin } from '../plugin';
@@ -90,50 +89,31 @@ export class PrivateAppImpl implements BackstageApp {
for (const output of plugin.output()) {
switch (output.type) {
case 'legacy-route': {
- const { path, component, options = {} } = output;
- const { exact = true } = options;
+ const { path, component: Component } = output;
routes.push(
- ,
+ } />,
);
break;
}
case 'route': {
- const { target, component, options = {} } = output;
- const { exact = true } = options;
+ const { target, component: Component } = output;
routes.push(
}
/>,
);
break;
}
case 'legacy-redirect-route': {
- const { path, target, options = {} } = output;
- const { exact = true } = options;
- routes.push(
- ,
- );
+ const { path, target } = output;
+ routes.push();
break;
}
case 'redirect-route': {
- const { from, to, options = {} } = output;
- const { exact = true } = options;
- routes.push(
- ,
- );
+ const { from, to } = output;
+ routes.push();
break;
}
case 'feature-flag': {
@@ -155,10 +135,10 @@ export class PrivateAppImpl implements BackstageApp {
}
const rendered = (
-
+
{routes}
-
-
+ } />
+
);
return () => rendered;
@@ -225,7 +205,7 @@ export class PrivateAppImpl implements BackstageApp {
- {children}
+ {children}
diff --git a/packages/core-api/src/app/types.ts b/packages/core-api/src/app/types.ts
index 44201d1464..e30c79dd73 100644
--- a/packages/core-api/src/app/types.ts
+++ b/packages/core-api/src/app/types.ts
@@ -25,12 +25,11 @@ export type BootErrorPageProps = {
step: 'load-config';
error: Error;
};
-
export type AppComponents = {
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType;
Progress: ComponentType<{}>;
- Router: ComponentType<{ basename?: string }>;
+ Router: ComponentType<{}>;
};
/**
diff --git a/packages/core/package.json b/packages/core/package.json
index 8a476a58d5..4f0d20b8ed 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -37,7 +37,6 @@
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@types/react": "^16.9",
- "@types/react-router-dom": "^5.1.5",
"@types/react-sparklines": "^1.7.0",
"classnames": "^2.2.6",
"clsx": "^1.1.0",
@@ -48,8 +47,8 @@
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-helmet": "6.0.0",
- "react-router": "^5.2.0",
- "react-router-dom": "^5.2.0",
+ "react-router": "6.0.0-alpha.5",
+ "react-router-dom": "6.0.0-alpha.5",
"react-sparklines": "^1.7.0",
"react-syntax-highlighter": "^12.2.1",
"react-use": "^14.2.0"
diff --git a/packages/core/src/components/Button/Button.stories.tsx b/packages/core/src/components/Button/Button.stories.tsx
index f7bbe45abd..aaca389f82 100644
--- a/packages/core/src/components/Button/Button.stories.tsx
+++ b/packages/core/src/components/Button/Button.stories.tsx
@@ -15,12 +15,7 @@
*/
import React, { FunctionComponentFactory } from 'react';
import { Button } from './Button';
-import {
- MemoryRouter,
- Route,
- useLocation,
- Link as RouterLink,
-} from 'react-router-dom';
+import { MemoryRouter, Route, useLocation } from 'react-router-dom';
import { createRouteRef } from '@backstage/core-api';
const Location = () => {
@@ -70,14 +65,7 @@ export const PassProps = () => {
return (
<>
-
} />
{buttonLabel}
- {testString}{' '}
- ,
+ ,
),
);
+
expect(() => getByText(testString)).toThrow();
await act(async () => fireEvent.click(getByText(buttonLabel)));
expect(getByText(testString)).toBeInTheDocument();
diff --git a/packages/core/src/components/Link/Link.test.jsx b/packages/core/src/components/Link/Link.test.jsx
index fcbc92a67a..4bb78ef6d4 100644
--- a/packages/core/src/components/Link/Link.test.jsx
+++ b/packages/core/src/components/Link/Link.test.jsx
@@ -18,7 +18,7 @@ import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { wrapInTestApp } from '@backstage/test-utils';
import { Link } from './Link';
-import { MemoryRouter, Route } from 'react-router';
+import { Route, Routes } from 'react-router';
import { act } from 'react-dom/test-utils';
describe('', () => {
@@ -27,10 +27,10 @@ describe('', () => {
const linkText = 'Navigate!';
const { getByText } = render(
wrapInTestApp(
-
+
{linkText}
- {testString}
- ,
+ {testString}} />
+ ,
),
);
expect(() => getByText(testString)).toThrow();
diff --git a/packages/core/src/components/Link/Link.tsx b/packages/core/src/components/Link/Link.tsx
index 859650e6b0..8e7e3f179e 100644
--- a/packages/core/src/components/Link/Link.tsx
+++ b/packages/core/src/components/Link/Link.tsx
@@ -19,7 +19,7 @@ import { Link as MaterialLink } from '@material-ui/core';
import { Link as RouterLink } from 'react-router-dom';
type Props = ComponentProps &
- ComponentProps;
+ ComponentProps & { component?: React.FC };
/**
* Thin wrapper on top of material-ui's Link component
diff --git a/packages/core/src/layout/ErrorPage/ErrorPage.tsx b/packages/core/src/layout/ErrorPage/ErrorPage.tsx
index b94c7409fc..d6620295c1 100644
--- a/packages/core/src/layout/ErrorPage/ErrorPage.tsx
+++ b/packages/core/src/layout/ErrorPage/ErrorPage.tsx
@@ -19,7 +19,7 @@ import { Typography, Link, Grid } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import { BackstageTheme } from '@backstage/theme';
import { MicDrop } from './MicDrop';
-import { useHistory } from 'react-router';
+import { useNavigate } from 'react-router';
interface IErrorPageProps {
status: string;
@@ -40,7 +40,7 @@ const useStyles = makeStyles(theme => ({
export const ErrorPage = ({ status, statusMessage }: IErrorPageProps) => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
return (
@@ -53,7 +53,7 @@ export const ErrorPage = ({ status, statusMessage }: IErrorPageProps) => {
Looks like someone dropped the mic!
-
+ navigate(-1)}>
Go back
... or if you think this is a bug, please file an{' '}
diff --git a/packages/core/src/layout/Sidebar/Items.tsx b/packages/core/src/layout/Sidebar/Items.tsx
index 4c7d4487da..5c2909f82e 100644
--- a/packages/core/src/layout/Sidebar/Items.tsx
+++ b/packages/core/src/layout/Sidebar/Items.tsx
@@ -121,7 +121,8 @@ export const SidebarItem: FC = ({
icon: Icon,
text,
to = '#',
- disableSelected = false,
+ // TODO: isActive is not in v6
+ // disableSelected = false,
hasNotifications = false,
onClick,
children,
@@ -148,8 +149,7 @@ export const SidebarItem: FC = ({
Boolean(match && !disableSelected)}
- exact
+ end
to={to}
onClick={onClick}
>
@@ -161,8 +161,7 @@ export const SidebarItem: FC = ({
Boolean(match && !disableSelected)}
- exact
+ end
to={to}
onClick={onClick}
>
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index 01753db4d8..95d3b6eb92 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -43,8 +43,8 @@
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-hot-loader": "^4.12.21",
- "react-router": "^5.2.0",
- "react-router-dom": "^5.2.0"
+ "react-router": "^6.0.0-alpha.5",
+ "react-router-dom": "^6.0.0-alpha.5"
},
"devDependencies": {
"@types/jest": "^25.2.2",
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index f48fe65c30..0e76d0239b 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -41,8 +41,8 @@
"@types/react": "^16.9",
"react": "^16.12.0",
"react-dom": "^16.12.0",
- "react-router": "^5.2.0",
- "react-router-dom": "^5.2.0"
+ "react-router": "^6.0.0-alpha.5",
+ "react-router-dom": "^6.0.0-alpha.5"
},
"devDependencies": {
"@types/jest": "^25.2.2",
diff --git a/packages/test-utils/src/testUtils/appWrappers.test.tsx b/packages/test-utils/src/testUtils/appWrappers.test.tsx
index 34a20be63b..19c02c2158 100644
--- a/packages/test-utils/src/testUtils/appWrappers.test.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.test.tsx
@@ -17,7 +17,7 @@
import React, { FC, useEffect } from 'react';
import { render } from '@testing-library/react';
import { wrapInTestApp, renderInTestApp } from './appWrappers';
-import { Route } from 'react-router';
+import { Route, Routes } from 'react-router';
import { withLogCollector } from '@backstage/test-utils-core';
import {
useApi,
@@ -32,15 +32,15 @@ describe('wrapInTestApp', () => {
const { error } = await withLogCollector(['error'], async () => {
const rendered = render(
wrapInTestApp(
- <>
- Route 1
- Route 2
- >,
+
+ Route 1} />
+ Route 2} />
+ ,
{ routeEntries: ['/route2'] },
),
);
- expect(rendered.getByText('Route 2')).toBeInTheDocument();
+ expect(rendered.getByText('Route 2')).toBeInTheDocument();
// Wait for async actions to trigger the act() warnings that we assert below
await Promise.resolve();
});
diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx
index 6cd3672558..c474678fd1 100644
--- a/packages/test-utils/src/testUtils/appWrappers.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.tsx
@@ -92,7 +92,9 @@ export function wrapInTestApp(
return (
-
+ {/* The path of * here is needed to be set as a catch all, so it will render the wrapper element
+ * and work with nested routes if they exist too */}
+ } />
);
}
diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json
index c6457aa8a8..21288ca046 100644
--- a/plugins/catalog/package.json
+++ b/plugins/catalog/package.json
@@ -32,8 +32,8 @@
"@material-ui/lab": "4.0.0-alpha.45",
"react": "^16.13.1",
"react-dom": "^16.13.1",
- "react-router": "^5.2.0",
- "react-router-dom": "^5.2.0",
+ "react-router": "^6.0.0-alpha.5",
+ "react-router-dom": "^6.0.0-alpha.5",
"react-use": "^14.2.0",
"swr": "^0.2.2"
},
diff --git a/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx b/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx
index 22a47c192e..aeb9fc543b 100644
--- a/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx
+++ b/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx
@@ -14,32 +14,38 @@
* limitations under the License.
*/
+jest.mock('react-router-dom', () => {
+ const actual = jest.requireActual('react-router-dom');
+ const mockNavigate = jest.fn();
+ return {
+ ...actual,
+ useNavigate: jest.fn(() => mockNavigate),
+ useParams: jest.fn(),
+ };
+});
+
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
import { wrapInTestApp } from '@backstage/test-utils';
import { render, wait } from '@testing-library/react';
import * as React from 'react';
import { CatalogApi, catalogApiRef } from '../../api/types';
import { EntityPage } from './EntityPage';
-
-const getTestProps = (name: string) => {
- return {
- match: {
- params: {
- optionalNamespaceAndName: name,
- kind: 'Component',
- },
- },
- history: {
- push: jest.fn(),
- },
- };
-};
+const {
+ useParams,
+ useNavigate,
+}: { useParams: jest.Mock; useNavigate: () => jest.Mock } = jest.requireMock(
+ 'react-router-dom',
+);
const errorApi = { post: () => {} };
describe('EntityPage', () => {
it('should redirect to catalog page when name is not provided', async () => {
- const props = getTestProps('');
+ useParams.mockReturnValue({
+ kind: 'Component',
+ optionalNamespaceAndName: '',
+ });
+
render(
wrapInTestApp(
{
],
])}
>
-
+
,
),
);
- await wait(() =>
- expect(props.history.push).toHaveBeenCalledWith('/catalog'),
- );
+ await wait(() => expect(useNavigate()).toHaveBeenCalledWith('/catalog'));
});
});
diff --git a/plugins/catalog/src/components/EntityPage/EntityPage.tsx b/plugins/catalog/src/components/EntityPage/EntityPage.tsx
index 96132819e8..e74276697b 100644
--- a/plugins/catalog/src/components/EntityPage/EntityPage.tsx
+++ b/plugins/catalog/src/components/EntityPage/EntityPage.tsx
@@ -34,21 +34,9 @@ import { catalogApiRef } from '../..';
import { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';
import { EntityMetadataCard } from '../EntityMetadataCard/EntityMetadataCard';
import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEntityDialog';
+import { useParams, useNavigate } from 'react-router-dom';
const REDIRECT_DELAY = 1000;
-
-type Props = {
- match: {
- params: {
- optionalNamespaceAndName: string;
- kind: string;
- };
- };
- history: {
- push: (url: string) => void;
- };
-};
-
function headerProps(
kind: string,
namespace: string | undefined,
@@ -68,8 +56,12 @@ function headerProps(
};
}
-export const EntityPage: FC = ({ match, history }) => {
- const { optionalNamespaceAndName, kind } = match.params;
+export const EntityPage: FC<{}> = () => {
+ const { optionalNamespaceAndName, kind } = useParams() as {
+ optionalNamespaceAndName: string;
+ kind: string;
+ };
+ const navigate = useNavigate();
const [name, namespace] = optionalNamespaceAndName.split(':').reverse();
const errorApi = useApi(errorApiRef);
@@ -85,19 +77,19 @@ export const EntityPage: FC = ({ match, history }) => {
if (!error && !loading && !entity) {
errorApi.post(new Error('Entity not found!'));
setTimeout(() => {
- history.push('/');
+ navigate('/');
}, REDIRECT_DELAY);
}
- }, [errorApi, history, error, loading, entity]);
+ }, [errorApi, navigate, error, loading, entity]);
if (!name) {
- history.push('/catalog');
+ navigate('/catalog');
return null;
}
const cleanUpAfterRemoval = async () => {
setConfirmationDialogOpen(false);
- history.push('/');
+ navigate('/');
};
const showRemovalDialog = () => setConfirmationDialogOpen(true);
diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json
index c1570eaaad..f3a9598b9d 100644
--- a/plugins/circleci/package.json
+++ b/plugins/circleci/package.json
@@ -42,8 +42,8 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-lazylog": "^4.5.2",
- "react-router": "^5.1.2",
- "react-router-dom": "^5.1.2",
+ "react-router": "^6.0.0-alpha.5",
+ "react-router-dom": "^6.0.0-alpha.5",
"react-use": "^14.2.0"
},
"devDependencies": {
diff --git a/plugins/circleci/src/components/App.tsx b/plugins/circleci/src/components/App.tsx
index 1649c01b70..5907146340 100644
--- a/plugins/circleci/src/components/App.tsx
+++ b/plugins/circleci/src/components/App.tsx
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { Switch, Route, MemoryRouter } from 'react-router';
+import { Route, MemoryRouter, Routes } from 'react-router';
import { BuildsPage, Builds } from '../pages/BuildsPage';
import { DetailedViewPage, BuildWithSteps } from '../pages/BuildWithStepsPage';
import { AppStateProvider } from '../state';
@@ -24,14 +24,13 @@ export const App = () => {
return (
<>
-
-
+
+ } />
}
/>
-
+
>
@@ -45,14 +44,10 @@ export const CircleCIWidget = () => (
<>
-
-
-
-
+
+ } />
+ } />
+
>
diff --git a/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx b/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx
index 29559e4fec..d454278255 100644
--- a/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx
+++ b/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx
@@ -33,8 +33,7 @@ import { gitOpsApiRef, Status } from '../../api';
import { transformRunStatus } from '../ProfileCatalog';
const ClusterPage: FC<{}> = () => {
- const params = useParams<{ owner: string; repo: string }>();
-
+ const params = useParams() as { owner: string; repo: string };
const [loginInfo] = useLocalStorage<{
token: string;
username: string;
diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json
index 1132ced6da..85d2c8a210 100644
--- a/plugins/graphiql/package.json
+++ b/plugins/graphiql/package.json
@@ -55,7 +55,7 @@
"@types/node": "^12.0.0",
"@types/testing-library__jest-dom": "^5.0.4",
"jest-fetch-mock": "^3.0.3",
- "react-router-dom": "^5.2.0"
+ "react-router-dom": "6.0.0-alpha.5"
},
"files": [
"dist/**/*.{js,d.ts}"
diff --git a/plugins/home-page/package.json b/plugins/home-page/package.json
index cf4b077dfc..56c8de21d8 100644
--- a/plugins/home-page/package.json
+++ b/plugins/home-page/package.json
@@ -41,7 +41,7 @@
"@types/node": "^12.0.0",
"@types/testing-library__jest-dom": "^5.0.4",
"jest-fetch-mock": "^3.0.3",
- "react-router-dom": "^5.2.0"
+ "react-router-dom": "6.0.0-alpha.5"
},
"files": [
"dist/**/*.{js,d.ts}"
diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json
index eeb6bfa0bd..fcc2c2b519 100644
--- a/plugins/lighthouse/package.json
+++ b/plugins/lighthouse/package.json
@@ -30,7 +30,7 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-markdown": "^4.3.1",
- "react-router-dom": "^5.2.0",
+ "react-router-dom": "6.0.0-alpha.5",
"react-use": "^14.2.0"
},
"devDependencies": {
diff --git a/plugins/lighthouse/src/components/AuditList/index.test.tsx b/plugins/lighthouse/src/components/AuditList/index.test.tsx
index bcd486e876..076bb5819a 100644
--- a/plugins/lighthouse/src/components/AuditList/index.test.tsx
+++ b/plugins/lighthouse/src/components/AuditList/index.test.tsx
@@ -16,13 +16,10 @@
jest.mock('react-router-dom', () => {
const actual = jest.requireActual('react-router-dom');
- const mocks = {
- replace: jest.fn(),
- push: jest.fn(),
- };
+ const mockNavigation = jest.fn();
return {
...actual,
- useHistory: jest.fn(() => mocks),
+ useNavigate: jest.fn(() => mockNavigation),
};
});
@@ -41,7 +38,7 @@ import AuditList from '.';
import * as data from '../../__fixtures__/website-list-response.json';
-const { useHistory } = jest.requireMock('react-router-dom');
+const { useNavigate } = jest.requireMock('react-router-dom');
const websiteListResponse = data as WebsiteListResponse;
describe('AuditList', () => {
@@ -145,7 +142,8 @@ describe('AuditList', () => {
);
const element = await rendered.findByLabelText(/Go to page 1/);
fireEvent.click(element);
- expect(useHistory().replace).toHaveBeenCalledWith(`/lighthouse?page=1`);
+
+ expect(useNavigate()).toHaveBeenCalledWith(`/lighthouse?page=1`);
});
});
});
diff --git a/plugins/lighthouse/src/components/AuditList/index.tsx b/plugins/lighthouse/src/components/AuditList/index.tsx
index 4dbbb05295..09ea882134 100644
--- a/plugins/lighthouse/src/components/AuditList/index.tsx
+++ b/plugins/lighthouse/src/components/AuditList/index.tsx
@@ -16,7 +16,7 @@
import React, { useState, useMemo, FC, ReactNode } from 'react';
import { useLocalStorage, useAsync } from 'react-use';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { Grid, Button } from '@material-ui/core';
import Alert from '@material-ui/lab/Alert';
import Pagination from '@material-ui/lab/Pagination';
@@ -65,7 +65,7 @@ const AuditList: FC<{}> = () => {
return 0;
}, [value?.total, value?.limit]);
- const history = useHistory();
+ const navigate = useNavigate();
let content: ReactNode = null;
if (value) {
@@ -77,7 +77,7 @@ const AuditList: FC<{}> = () => {
page={page}
count={pageCount}
onChange={(_event: Event, newPage: number) => {
- history.replace(`/lighthouse?page=${newPage}`);
+ navigate(`/lighthouse?page=${newPage}`);
}}
/>
)}
diff --git a/plugins/lighthouse/src/components/AuditView/index.tsx b/plugins/lighthouse/src/components/AuditView/index.tsx
index 889c6c53f3..d323b1a005 100644
--- a/plugins/lighthouse/src/components/AuditView/index.tsx
+++ b/plugins/lighthouse/src/components/AuditView/index.tsx
@@ -18,10 +18,10 @@ import { Link, useParams } from 'react-router-dom';
import { useAsync } from 'react-use';
import {
makeStyles,
- Button,
Grid,
List,
ListItem,
+ Button,
ListItemIcon,
ListItemText,
} from '@material-ui/core';
@@ -68,7 +68,7 @@ const AuditLinkList: FC = ({
component="nav"
aria-label="lighthouse audit history"
>
- {audits.map((audit) => (
+ {audits.map(audit => (
= ({
const AuditView: FC<{ audit?: Audit }> = ({ audit }: { audit?: Audit }) => {
const classes = useStyles();
- const params = useParams<{ id: string }>();
+ const params = useParams() as { id: string };
const { url: lighthouseUrl } = useApi(lighthouseApiRef);
if (audit?.status === 'RUNNING') return ;
@@ -114,7 +114,7 @@ const AuditView: FC<{ audit?: Audit }> = ({ audit }: { audit?: Audit }) => {
const ConnectedAuditView: FC<{}> = () => {
const lighthouseApi = useApi(lighthouseApiRef);
- const params = useParams<{ id: string }>();
+ const params = useParams() as { id: string };
const classes = useStyles();
const { loading, error, value: nextValue } = useAsync(
@@ -136,7 +136,7 @@ const ConnectedAuditView: FC<{}> = () => {
- a.id === params.id)} />
+ a.id === params.id)} />
);
diff --git a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx
index 08e8005530..ee0404fc22 100644
--- a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx
+++ b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx
@@ -16,13 +16,10 @@
jest.mock('react-router-dom', () => {
const actual = jest.requireActual('react-router-dom');
- const mocks = {
- replace: jest.fn(),
- push: jest.fn(),
- };
+ const mockNavigate = jest.fn();
return {
...actual,
- useHistory: jest.fn(() => mocks),
+ useNavigate: jest.fn(() => mockNavigate),
};
});
@@ -41,7 +38,7 @@ import { lighthouseApiRef, LighthouseRestApi, Audit } from '../../api';
import CreateAudit from '.';
import * as data from '../../__fixtures__/create-audit-response.json';
-const { useHistory }: { useHistory: jest.Mock } = jest.requireMock(
+const { useNavigate }: { useNavigate: jest.Mock } = jest.requireMock(
'react-router-dom',
);
const createAuditResponse = data as Audit;
@@ -115,7 +112,7 @@ describe('CreateAudit', () => {
describe('when the audit is successfully created', () => {
it('triggers a location change to the table', async () => {
- useHistory().push.mockClear();
+ useNavigate.mockClear();
mockFetch.mockResponseOnce(JSON.stringify(createAuditResponse));
const rendered = render(
@@ -140,7 +137,7 @@ describe('CreateAudit', () => {
await wait(() => expect(rendered.getByLabelText(/URL/)).toBeEnabled());
- expect(useHistory().push).toHaveBeenCalledWith('/lighthouse');
+ expect(useNavigate()).toHaveBeenCalledWith('/lighthouse');
});
});
diff --git a/plugins/lighthouse/src/components/CreateAudit/index.tsx b/plugins/lighthouse/src/components/CreateAudit/index.tsx
index 55ae99d1db..a699e148c8 100644
--- a/plugins/lighthouse/src/components/CreateAudit/index.tsx
+++ b/plugins/lighthouse/src/components/CreateAudit/index.tsx
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React, { useState, useCallback, FC } from 'react';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import {
makeStyles,
Grid,
@@ -40,7 +40,7 @@ import { lighthouseApiRef } from '../../api';
import { useQuery } from '../../utils';
import LighthouseSupportButton from '../SupportButton';
-const useStyles = makeStyles((theme) => ({
+const useStyles = makeStyles(theme => ({
input: {
minWidth: 300,
},
@@ -58,7 +58,7 @@ const CreateAudit: FC<{}> = () => {
const lighthouseApi = useApi(lighthouseApiRef);
const classes = useStyles();
const query = useQuery();
- const history = useHistory();
+ const navigate = useNavigate();
const [submitting, setSubmitting] = useState(false);
const [url, setUrl] = useState(query.get('url') || '');
const [emulatedFormFactor, setEmulatedFormFactor] = useState('mobile');
@@ -78,7 +78,7 @@ const CreateAudit: FC<{}> = () => {
},
},
});
- history.push('/lighthouse');
+ navigate('/lighthouse');
} catch (err) {
errorApi.post(err);
} finally {
@@ -90,7 +90,7 @@ const CreateAudit: FC<{}> = () => {
lighthouseApi,
setSubmitting,
errorApi,
- history,
+ navigate,
]);
return (
@@ -113,7 +113,7 @@ const CreateAudit: FC<{}> = () => {