mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(react): avoid multiple invocations of onDidDismiss and onWillPresent (#28020)
Issue number: Resolves #28010 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> `onDidDismiss` and `onWillPresent` will fire twice when having a manual binding in your implementation for inline overlays. e.g.: ```tsx <IonAlert onDidDismiss={() => console.log('hello world')} /> ``` Will result in: > hello world > hello world ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - `onDidDismiss` and `onWillPresent` do not execute the callback handler twice per invocation ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev-build: `7.3.1-dev.11692305436.16a4008f`
This commit is contained in:
@@ -63,7 +63,14 @@ export const createInlineOverlayComponent = <PropType, ElementType>(
|
||||
|
||||
componentDidUpdate(prevProps: IonicReactInternalProps<PropType>) {
|
||||
const node = this.ref.current! as HTMLElement;
|
||||
attachProps(node, this.props, prevProps);
|
||||
/**
|
||||
* onDidDismiss and onWillPresent have manual implementations that
|
||||
* will invoke the original handler. We need to filter those out
|
||||
* so they don't get attached twice and called twice.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { onDidDismiss, onWillPresent, ...cProps } = this.props;
|
||||
attachProps(node, cProps, prevProps);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, IonActionSheet } from '@ionic/react';
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const ActionSheetComponent: React.FC = () => {
|
||||
const [message, setMessage] = useState('');
|
||||
const [show, setShow] = useState(false);
|
||||
const [willPresentCount, setWillPresentCount] = useState(0);
|
||||
const [didDismissCount, setDidDismissCount] = useState(0);
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
@@ -26,7 +27,13 @@ const ActionSheetComponent: React.FC = () => {
|
||||
},
|
||||
]}
|
||||
header="Action Sheet"
|
||||
onDidDismiss={() => setShow(false)}
|
||||
onWillPresent={() => {
|
||||
setWillPresentCount(willPresentCount + 1);
|
||||
}}
|
||||
onDidDismiss={() => {
|
||||
setDidDismissCount(didDismissCount + 1);
|
||||
setShow(false);
|
||||
}}
|
||||
/>
|
||||
<IonButton expand="block" onClick={() => setShow(true)}>
|
||||
Show ActionSheet
|
||||
@@ -41,6 +48,8 @@ const ActionSheetComponent: React.FC = () => {
|
||||
Show ActionSheet, hide after 250 mss
|
||||
</IonButton>
|
||||
<div>{message}</div>
|
||||
<div>onWillPresent count: {willPresentCount}</div>
|
||||
<div>onDidDismiss count: {didDismissCount}</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
|
||||
@@ -17,11 +17,19 @@ describe('IonActionSheet', () => {
|
||||
});
|
||||
|
||||
it('display action and call dismiss to close it', () => {
|
||||
//show action sheet
|
||||
cy.get('ion-content').contains('onWillPresent count: 0');
|
||||
cy.get('ion-content').contains('onDidDismiss count: 0');
|
||||
|
||||
// show action sheet
|
||||
cy.get('ion-button').contains('Show ActionSheet, hide after 250 ms').click();
|
||||
cy.get('ion-action-sheet').contains('Action Sheet');
|
||||
|
||||
//verify action sheet is hidden
|
||||
// verify action sheet is hidden
|
||||
cy.get('ion-action-sheet').should('not.be.visible');
|
||||
|
||||
// verify lifecycle events are called once
|
||||
cy.get('ion-content').contains('onWillPresent count: 1');
|
||||
cy.get('ion-content').contains('onDidDismiss count: 0');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user