Skip to content

Commit 6a3b011

Browse files
refactor(router): replace withRouter with hooks
`react-router-dom` has `withRouter` that passes information via a higher-order component. This is fine, but it has fairly complex types that TS is only happy with when it's a default export. When we change to using named exports this will cause a build error. See microsoft/TypeScript#42873.
1 parent 3a58436 commit 6a3b011

File tree

5 files changed

+17
-43
lines changed

5 files changed

+17
-43
lines changed

apps/bmd/src/components/FocusManager.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useRef } from 'react';
2-
import { RouteComponentProps, withRouter } from 'react-router-dom';
2+
import { useLocation } from 'react-router-dom';
33
import styled from 'styled-components';
44
import { ScreenReader } from '../utils/ScreenReader';
55

@@ -10,7 +10,7 @@ const StyledFocusManager = styled.div`
1010
}
1111
`;
1212

13-
export interface Props extends RouteComponentProps {
13+
export interface Props {
1414
children: React.ReactNode;
1515
onClick?: React.DOMAttributes<HTMLElement>['onClick'];
1616
onClickCapture?: React.DOMAttributes<HTMLElement>['onClickCapture'];
@@ -21,7 +21,7 @@ export interface Props extends RouteComponentProps {
2121
screenReader: ScreenReader;
2222
}
2323

24-
function FocusManager({
24+
export default function FocusManager({
2525
onKeyPress,
2626
onClick,
2727
onFocus,
@@ -30,8 +30,8 @@ function FocusManager({
3030
onFocusCapture,
3131
children,
3232
screenReader,
33-
location,
3433
}: Props): JSX.Element {
34+
const location = useLocation();
3535
const screen = useRef<HTMLDivElement>(null);
3636
useEffect(() => {
3737
function onPageLoad() {
@@ -67,5 +67,3 @@ function FocusManager({
6767
</StyledFocusManager>
6868
);
6969
}
70-
71-
export default withRouter(FocusManager);

apps/bmd/src/pages/StartPage.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { strict as assert } from 'assert';
22
import React, { useContext, useEffect, useRef } from 'react';
33
import styled from 'styled-components';
4-
import { RouteComponentProps, withRouter } from 'react-router-dom';
4+
import { useHistory } from 'react-router-dom';
55
import { getPartyPrimaryAdjectiveFromBallotStyle } from '@votingworks/types';
66
import { LinkButton, Main, MainChild } from '@votingworks/ui';
77

@@ -19,9 +19,8 @@ const SidebarSpacer = styled.div`
1919
height: 90px;
2020
`;
2121

22-
type Props = RouteComponentProps<Record<string, string | undefined>>;
23-
24-
function StartPage({ history }: Props): JSX.Element {
22+
export default function StartPage(): JSX.Element {
23+
const history = useHistory();
2524
const {
2625
ballotStyleId,
2726
contests,
@@ -121,5 +120,3 @@ function StartPage({ history }: Props): JSX.Element {
121120
</Screen>
122121
);
123122
}
124-
125-
export default withRouter(StartPage);

apps/bsd/src/components/LinkButton.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import React from 'react';
2-
import { RouteComponentProps, withRouter } from 'react-router-dom';
2+
import { useHistory } from 'react-router-dom';
33
import { EventTargetFunction } from '../config/types';
44

55
import Button, { ButtonInterface } from './Button';
66

77
interface Props
88
extends ButtonInterface,
9-
// eslint-disable-next-line @typescript-eslint/ban-types
10-
RouteComponentProps<{}>,
119
React.PropsWithoutRef<JSX.IntrinsicElements['button']> {}
1210

1311
interface Props {
@@ -17,14 +15,11 @@ interface Props {
1715
to?: string;
1816
}
1917

20-
function LinkButton(props: Props) {
18+
export default function LinkButton(props: Props): JSX.Element {
19+
const history = useHistory();
2120
const {
2221
goBack,
23-
history,
24-
location, // eslint-disable-line @typescript-eslint/no-unused-vars
25-
match, // eslint-disable-line @typescript-eslint/no-unused-vars
2622
onPress,
27-
staticContext, // eslint-disable-line @typescript-eslint/no-unused-vars
2823
to,
2924
// ⬆ filtering out props which are not intrinsic to `<button>` element.
3025
...rest
@@ -47,5 +42,3 @@ function LinkButton(props: Props) {
4742
/>
4843
);
4944
}
50-
51-
export default withRouter(LinkButton);

apps/election-manager/src/components/LinkButton.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,27 @@
11
import React from 'react';
2-
import { RouteComponentProps, withRouter } from 'react-router-dom';
2+
import { useHistory } from 'react-router-dom';
33
import { EventTargetFunction } from '../config/types';
44

55
import Button, { ButtonInterface } from './Button';
66

77
interface Props
88
extends ButtonInterface,
9-
// eslint-disable-next-line @typescript-eslint/ban-types
10-
RouteComponentProps<{}>,
119
React.PropsWithoutRef<JSX.IntrinsicElements['button']> {
1210
goBack?: boolean;
1311
onPress?: EventTargetFunction;
1412
primary?: boolean;
1513
to?: string;
1614
}
1715

18-
function LinkButton(props: Props) {
16+
export default function LinkButton(props: Props): JSX.Element {
1917
const {
2018
goBack,
21-
history,
22-
location, // eslint-disable-line @typescript-eslint/no-unused-vars
23-
match, // eslint-disable-line @typescript-eslint/no-unused-vars
2419
onPress,
25-
staticContext, // eslint-disable-line @typescript-eslint/no-unused-vars
2620
to,
2721
// ⬆ filtering out props which are not intrinsic to `<button>` element.
2822
...rest
2923
} = props;
24+
const history = useHistory();
3025
const handleOnPress: EventTargetFunction = (event) => {
3126
/* istanbul ignore else */
3227
if (onPress) {
@@ -45,5 +40,3 @@ function LinkButton(props: Props) {
4540
/>
4641
);
4742
}
48-
49-
export default withRouter(LinkButton);

libs/ui/src/LinkButton.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
import React from 'react';
2-
import { RouteComponentProps, withRouter } from 'react-router-dom';
2+
import { useHistory } from 'react-router-dom';
33
import { EventTargetFunction } from '@votingworks/types';
44
import { Button, ButtonProps } from './Button';
55

6-
export interface LinkButtonProps
7-
extends Omit<ButtonProps, 'onPress'>,
8-
RouteComponentProps<Record<string, string | undefined>> {
6+
export interface LinkButtonProps extends Omit<ButtonProps, 'onPress'> {
97
goBack?: boolean;
108
onPress?: EventTargetFunction;
119
primary?: boolean;
1210
to?: string;
1311
}
1412

15-
function LinkButton(props: LinkButtonProps): JSX.Element {
13+
export default function LinkButton(props: LinkButtonProps): JSX.Element {
14+
const history = useHistory();
1615
const {
1716
goBack,
18-
history,
19-
location, // eslint-disable-line @typescript-eslint/no-unused-vars
20-
match, // eslint-disable-line @typescript-eslint/no-unused-vars
2117
onPress,
22-
staticContext, // eslint-disable-line @typescript-eslint/no-unused-vars
2318
to,
2419
// ⬆ filtering out props which are not intrinsic to `<button>` element.
2520
...rest
@@ -42,5 +37,3 @@ function LinkButton(props: LinkButtonProps): JSX.Element {
4237
/>
4338
);
4439
}
45-
46-
export default withRouter(LinkButton);

0 commit comments

Comments
 (0)