mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(react-router): include search params in navigation change detection
This commit is contained in:
@@ -177,7 +177,7 @@ export const IonRouter = ({ children, registerHistoryListener }: PropsWithChildr
|
||||
}
|
||||
|
||||
const leavingUrl = leavingLocationInfo.pathname + leavingLocationInfo.search;
|
||||
if (leavingUrl !== location.pathname) {
|
||||
if (leavingUrl !== location.pathname + location.search) {
|
||||
if (!incomingRouteParams.current) {
|
||||
// Determine if the destination is a tab route by checking if it matches
|
||||
// the pattern of tab routes (containing /tabs/ in the path)
|
||||
|
||||
@@ -46,6 +46,7 @@ import Overlays from './pages/overlays/Overlays';
|
||||
import NestedTabsRelativeLinks from './pages/nested-tabs-relative-links/NestedTabsRelativeLinks';
|
||||
import RootSplatTabs from './pages/root-splat-tabs/RootSplatTabs';
|
||||
import ContentChangeNavigation from './pages/content-change-navigation/ContentChangeNavigation';
|
||||
import SearchParams from './pages/search-params/SearchParams';
|
||||
|
||||
setupIonicReact();
|
||||
|
||||
@@ -81,6 +82,7 @@ const App: React.FC = () => {
|
||||
<Route path="/nested-tabs-relative-links/*" element={<NestedTabsRelativeLinks />} />
|
||||
<Route path="/root-splat-tabs/*" element={<RootSplatTabs />} />
|
||||
<Route path="/content-change-navigation/*" element={<ContentChangeNavigation />} />
|
||||
<Route path="/search-params" element={<SearchParams />} />
|
||||
</IonRouterOutlet>
|
||||
</IonReactRouter>
|
||||
</IonApp>
|
||||
|
||||
@@ -83,6 +83,9 @@ const Main: React.FC = () => {
|
||||
<IonItem routerLink="/content-change-navigation">
|
||||
<IonLabel>Content Change Navigation</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem routerLink="/search-params">
|
||||
<IonLabel>Search Params</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
IonBackButton,
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
} from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
|
||||
const SearchParams: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [searchParams] = useSearchParams();
|
||||
const query = searchParams.get('q') || '';
|
||||
|
||||
return (
|
||||
<IonPage data-pageid="search-params">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonButtons slot="start">
|
||||
<IonBackButton />
|
||||
</IonButtons>
|
||||
<IonTitle>Search Params</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<div id="current-path">{location.pathname + location.search}</div>
|
||||
<div id="query-value">{query}</div>
|
||||
<IonButton id="add-search" onClick={() => navigate('/search-params?q=test')}>
|
||||
Add Search Param
|
||||
</IonButton>
|
||||
<IonButton id="change-search" onClick={() => navigate('/search-params?q=changed')}>
|
||||
Change Search Param
|
||||
</IonButton>
|
||||
<IonButton id="remove-search" onClick={() => navigate('/search-params')}>
|
||||
Remove Search Param
|
||||
</IonButton>
|
||||
<IonButton id="go-home" routerLink="/">
|
||||
Go Home
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchParams;
|
||||
@@ -0,0 +1,88 @@
|
||||
describe('Search Params Navigation', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/search-params');
|
||||
// Wait for the page to be visible
|
||||
cy.get('[data-pageid="search-params"]').should('be.visible');
|
||||
});
|
||||
|
||||
it('should navigate when adding search params to the same path', () => {
|
||||
// Verify we start without search params
|
||||
cy.get('#current-path').should('have.text', '/search-params');
|
||||
cy.get('#query-value').should('have.text', '');
|
||||
|
||||
// Click to add search param - this navigates from /search-params to /search-params?q=test
|
||||
cy.get('#add-search').click();
|
||||
|
||||
// The URL should update with the search param
|
||||
cy.location('pathname').should('eq', '/search-params');
|
||||
cy.location('search').should('eq', '?q=test');
|
||||
|
||||
// The component should re-render with the new search param value
|
||||
cy.get('#current-path').should('have.text', '/search-params?q=test');
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
});
|
||||
|
||||
it('should navigate when changing search params on the same path', () => {
|
||||
// First add a search param
|
||||
cy.get('#add-search').click();
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
|
||||
// Now change the search param
|
||||
cy.get('#change-search').click();
|
||||
|
||||
cy.location('search').should('eq', '?q=changed');
|
||||
cy.get('#current-path').should('have.text', '/search-params?q=changed');
|
||||
cy.get('#query-value').should('have.text', 'changed');
|
||||
});
|
||||
|
||||
it('should navigate when removing search params from the same path', () => {
|
||||
// First add a search param
|
||||
cy.get('#add-search').click();
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
|
||||
// Now remove the search param
|
||||
cy.get('#remove-search').click();
|
||||
|
||||
cy.location('search').should('eq', '');
|
||||
cy.get('#current-path').should('have.text', '/search-params');
|
||||
cy.get('#query-value').should('have.text', '');
|
||||
});
|
||||
|
||||
it('should restore search params when navigating back from another page', () => {
|
||||
// Add search param
|
||||
cy.get('#add-search').click();
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
cy.location('search').should('eq', '?q=test');
|
||||
|
||||
// Navigate to home page
|
||||
cy.get('#go-home').click();
|
||||
cy.get('[data-pageid="home"]').should('be.visible');
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
// Go back - should restore /search-params?q=test
|
||||
cy.go('back');
|
||||
cy.get('[data-pageid="search-params"]').should('be.visible');
|
||||
cy.location('pathname').should('eq', '/search-params');
|
||||
cy.location('search').should('eq', '?q=test');
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
});
|
||||
|
||||
it('should support back through multiple search param changes', () => {
|
||||
// Navigate: /search-params -> /search-params?q=test -> /search-params?q=changed
|
||||
cy.get('#add-search').click();
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
|
||||
cy.get('#change-search').click();
|
||||
cy.get('#query-value').should('have.text', 'changed');
|
||||
|
||||
// Go back to ?q=test
|
||||
cy.go('back');
|
||||
cy.location('search').should('eq', '?q=test');
|
||||
cy.get('#query-value').should('have.text', 'test');
|
||||
|
||||
// Go back to no search params
|
||||
cy.go('back');
|
||||
cy.location('search').should('eq', '');
|
||||
cy.get('#query-value').should('have.text', '');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user