Skip to content

Commit 3b325d7

Browse files
authored
refactor: use const for navigate(-1) and navigate('/'); also migrate the remaining files to v5-compat (#37819)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/37819?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: partial is for MetaMask/MetaMask-planning#6231 ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Replace history-based navigation with v5-compat navigate and PREVIOUS_ROUTE/DEFAULT_ROUTE across the app, updating routing scaffolding, components, hooks, tests, and stories. > > - **Router/Navigation**: > - Add v5-to-v5-compat `navigate` bridge in `routes.component.tsx`; pass `navigate`, `location`, and `params` to v5-compat components via helpers. > - Replace `navigate(-1)` with `navigate(PREVIOUS_ROUTE)`; standardize uses of `DEFAULT_ROUTE` and other route constants. > - Switch to `react-router-dom-v5-compat` APIs (`useNavigate`, `useLocation`, `useMatch`, `matchPath`) across files. > - **Components**: > - Update many components to accept/use `navigate` instead of `history` (e.g., `Alerts`, `InvalidCustomNetworkAlert`, `HideTokenConfirmationModal`, `NicknamePopover`, SRP-related components, NFT image view, transaction details, permissions page, snaps list/view, home, connected accounts/sites, asset options/token asset, notifications settings, wallet/account details). > - Use `PREVIOUS_ROUTE` for back actions (e.g., SRP flows, bridge tx details, send hooks, confirm flows). > - **Hooks/Utils**: > - Migrate hooks to v5-compat (`useClaimState`, `useCurrentAsset`, `useSegmentContext`). > - Update `utils.js` route matching to v5-compat `matchPath` signature. > - **Tests/Stories**: > - Update tests to use navigate-aware render helpers and constants (`DEFAULT_ROUTE`, `PREVIOUS_ROUTE`); adjust mocks accordingly. > - Storybook: replace MemoryRouter usage where needed; pass `navigate` args. > - **Misc**: > - Minor cleanup in `rewards` slice (remove extraneous whitespace). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dc9beda. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent ce354f7 commit 3b325d7

File tree

70 files changed

+701
-476
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+701
-476
lines changed

ui/components/app/alerts/alerts.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import PropTypes from 'prop-types';
55
import { alertIsOpen as invalidCustomNetworkAlertIsOpen } from '../../../ducks/alerts/invalid-custom-network';
66
import InvalidCustomNetworkAlert from './invalid-custom-network-alert';
77

8-
const Alerts = ({ history }) => {
8+
const Alerts = ({ navigate }) => {
99
const _invalidCustomNetworkAlertIsOpen = useSelector(
1010
invalidCustomNetworkAlertIsOpen,
1111
);
1212

1313
if (_invalidCustomNetworkAlertIsOpen) {
14-
return <InvalidCustomNetworkAlert history={history} />;
14+
return <InvalidCustomNetworkAlert navigate={navigate} />;
1515
}
1616

1717
return null;
1818
};
1919

2020
Alerts.propTypes = {
21-
history: PropTypes.object.isRequired,
21+
navigate: PropTypes.func.isRequired,
2222
};
2323

2424
export default Alerts;

ui/components/app/alerts/invalid-custom-network-alert/invalid-custom-network-alert.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { NETWORKS_ROUTE } from '../../../../helpers/constants/routes';
1515

1616
const { ERROR, LOADING } = ALERT_STATE;
1717

18-
const InvalidCustomNetworkAlert = ({ history }) => {
18+
const InvalidCustomNetworkAlert = ({ navigate }) => {
1919
const t = useI18nContext();
2020
const dispatch = useDispatch();
2121
const alertState = useSelector(getAlertState);
@@ -43,7 +43,7 @@ const InvalidCustomNetworkAlert = ({ history }) => {
4343
disabled={alertState === LOADING}
4444
onClick={async () => {
4545
await onClose();
46-
history.push(NETWORKS_ROUTE);
46+
navigate(NETWORKS_ROUTE);
4747
}}
4848
variant={ButtonVariant.Primary}
4949
className="invalid-custom-network-alert__footer-row-button"
@@ -82,7 +82,7 @@ const InvalidCustomNetworkAlert = ({ history }) => {
8282
};
8383

8484
InvalidCustomNetworkAlert.propTypes = {
85-
history: PropTypes.object.isRequired,
85+
navigate: PropTypes.func.isRequired,
8686
};
8787

8888
export default InvalidCustomNetworkAlert;

ui/components/app/alerts/invalid-custom-network-alert/invalid-custom-network-alert.stories.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ const meta: Meta<typeof InvalidCustomNetworkAlert> = {
2525
),
2626
],
2727
argTypes: {
28-
history: {
29-
control: 'object',
28+
navigate: {
29+
control: 'function',
3030
},
3131
},
3232
args: {
33-
history: {
34-
push: () => {},
35-
},
33+
navigate: () => {},
3634
},
3735
};
3836

ui/components/app/assets/nfts/nft-details/nft-full-image.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ import useFetchNftDetailsFromTokenURI from '../../../../../hooks/useFetchNftDeta
3030
import { isWebUrl } from '../../../../../../app/scripts/lib/util';
3131
import { getNetworkConfigurationsByChainId } from '../../../../../../shared/modules/selectors/networks';
3232
import { getImageForChainId } from '../../../../../selectors/multichain';
33-
import { ASSET_ROUTE } from '../../../../../helpers/constants/routes';
33+
import {
34+
ASSET_ROUTE,
35+
PREVIOUS_ROUTE,
36+
} from '../../../../../helpers/constants/routes';
3437

3538
type NftFullImageProps = {
3639
params?: {
@@ -102,7 +105,7 @@ export default function NftFullImage({ params }: NftFullImageProps) {
102105
const onClose = useCallback(() => {
103106
if (navigationType === 'PUSH') {
104107
// Previous navigation was a PUSH, so safe to go back
105-
navigate(-1);
108+
navigate(PREVIOUS_ROUTE);
106109
} else {
107110
// Fallback: go to the asset details route explicitly
108111
navigate(`${ASSET_ROUTE}/${hexChainId}/${asset}/${id}`, {

ui/components/app/modals/hide-token-confirmation-modal/hide-token-confirmation-modal.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function mapStateToProps(state) {
2222
return {
2323
chainId: getCurrentChainId(state),
2424
token: state.appState.modal.modalState.props.token,
25-
history: state.appState.modal.modalState.props.history,
25+
navigate: state.appState.modal.modalState.props.navigate,
2626
networkConfigurationsByChainId: getNetworkConfigurationsByChainId(state),
2727
getAccountForChain: (caipChainId) =>
2828
getInternalAccountBySelectedAccountGroupAndCaip(state, caipChainId),
@@ -85,7 +85,7 @@ class HideTokenConfirmationModal extends Component {
8585
image: PropTypes.string,
8686
chainId: PropTypes.string,
8787
}),
88-
history: PropTypes.object,
88+
navigate: PropTypes.func,
8989
};
9090

9191
state = {};
@@ -96,7 +96,7 @@ class HideTokenConfirmationModal extends Component {
9696
token,
9797
hideToken,
9898
hideModal,
99-
history,
99+
navigate,
100100
networkConfigurationsByChainId,
101101
getAccountForChain,
102102
} = this.props;
@@ -154,7 +154,7 @@ class HideTokenConfirmationModal extends Component {
154154
getAccountForChain,
155155
);
156156
}
157-
history.push(DEFAULT_ROUTE);
157+
navigate(DEFAULT_ROUTE);
158158
}}
159159
>
160160
{this.context.t('hide')}

ui/components/app/modals/hide-token-confirmation-modal/hide-token-confirmation-modal.test.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import configureMockStore from 'redux-mock-store';
33
import { fireEvent } from '@testing-library/react';
44
import thunk from 'redux-thunk';
55
import * as actions from '../../../../store/actions';
6-
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
6+
import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
77
import mockState from '../../../../../test/data/mock-state.json';
88
import { mockNetworkState } from '../../../../../test/stub/networks';
99
import HideTokenConfirmationModal from '.';
1010

11-
const mockHistoryPush = jest.fn();
11+
const mockUseNavigate = jest.fn();
1212
const mockHideModal = jest.fn();
1313
const mockHideToken = jest.fn().mockResolvedValue();
1414

@@ -40,9 +40,7 @@ describe('Hide Token Confirmation Modal', () => {
4040
modal: {
4141
modalState: {
4242
props: {
43-
history: {
44-
push: mockHistoryPush,
45-
},
43+
navigate: mockUseNavigate,
4644
token: tokenState,
4745
},
4846
},
@@ -105,9 +103,7 @@ describe('Hide Token Confirmation Modal', () => {
105103
modal: {
106104
modalState: {
107105
props: {
108-
history: {
109-
push: mockHistoryPush,
110-
},
106+
navigate: mockUseNavigate,
111107
token: tokenState2,
112108
},
113109
},

ui/components/app/modals/nickname-popovers/nickname-popovers.component.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { fireEvent } from '@testing-library/react';
33
import { BtcAccountType } from '@metamask/keyring-api';
4-
import { renderWithProvider } from '../../../../../test/jest';
4+
import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
55
import configureStore from '../../../../store/store';
66
import mockState from '../../../../../test/data/mock-state.json';
77
import {

ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const DefaultStory: StoryFn<typeof SRPQuiz> = () => {
2626
<SRPQuiz
2727
isOpen={isShowingModal}
2828
onClose={() => updateArgs({ isShowingModal: false })}
29+
navigate={() => {}}
2930
/>
3031
)}
3132
</>

ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ describe('srp-reveal-quiz', () => {
3232
});
3333

3434
it('should go through the full sequence of steps', async () => {
35-
renderWithProvider(<SRPQuiz isOpen />, store);
35+
const mockNavigate = jest.fn();
36+
renderWithProvider(<SRPQuiz isOpen navigate={mockNavigate} />, store);
3637

3738
expect(screen.queryByTestId('srp-quiz-get-started')).toBeInTheDocument();
3839

ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, import/no-commonjs */
22
import React, { useCallback, useContext, useEffect, useState } from 'react';
3-
import { useHistory } from 'react-router-dom';
43
import { useSelector } from 'react-redux';
4+
import type { To } from 'react-router-dom-v5-compat';
55
import {
66
MetaMetricsEventCategory,
77
MetaMetricsEventKeyType,
@@ -64,6 +64,13 @@ export type SRPQuizProps = {
6464
isOpen: boolean;
6565
onClose: () => void;
6666
closeAfterCompleting?: boolean;
67+
navigate: {
68+
(
69+
to: To,
70+
options?: { replace?: boolean; state?: Record<string, unknown> },
71+
): void;
72+
(delta: number): void;
73+
};
6774
};
6875

6976
// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
@@ -72,7 +79,6 @@ export default function SRPQuiz(props: SRPQuizProps): JSX.Element {
7279
const [stage, setStage] = useState<QuizStage>(QuizStage.introduction);
7380

7481
const trackEvent = useContext(MetaMetricsContext);
75-
const history = useHistory();
7682
const t = useI18nContext();
7783
const hdEntropyIndex = useSelector(getHDEntropyIndex);
7884

@@ -237,7 +243,7 @@ export default function SRPQuiz(props: SRPQuizProps): JSX.Element {
237243
route = `${REVEAL_SEED_ROUTE}/${props.keyringId}`;
238244
}
239245

240-
history.push(route);
246+
props.navigate(route);
241247
if (props.closeAfterCompleting) {
242248
props.onClose();
243249
}

0 commit comments

Comments
 (0)