fix(react): prevent errors when dismissing inline popover after containing element is removed (#24569)

This commit is contained in:
Amanda Smith
2022-01-12 14:51:50 -06:00
committed by GitHub
parent 273ae2cc08
commit c8a392aef5
3 changed files with 28 additions and 3 deletions

View File

@ -78,10 +78,19 @@ export const createInlineOverlayComponent = <PropType, ElementType>(
* cleanup properly. * cleanup properly.
*/ */
this.ref.current?.addEventListener('didDismiss', (evt: any) => { this.ref.current?.addEventListener('didDismiss', (evt: any) => {
const wrapper = this.wrapperRef.current!; const wrapper = this.wrapperRef.current;
this.ref.current!.append(wrapper); const el = this.ref.current;
this.setState({ isOpen: false }); /**
* This component might be unmounted already, if the containing
* element was removed while the popover was still open. (For
* example, if an item contains an inline popover with a button
* that removes the item.)
*/
if (wrapper && el) {
el.append(wrapper);
this.setState({ isOpen: false });
}
this.props.onDidDismiss && this.props.onDidDismiss(evt); this.props.onDidDismiss && this.props.onDidDismiss(evt);
}); });

View File

@ -18,4 +18,12 @@ describe('IonPopover', () => {
cy.get('ion-popover ion-list-header').contains('Ionic'); cy.get('ion-popover ion-list-header').contains('Ionic');
}); });
it('display popover and remove containing element', () => {
//show popover, remove containing item
cy.get('#openPopover').click();
cy.get('#removeItem').click();
//verify popover is gone
cy.get('#popoverInItem').should('not.exist');
});
}); });

View File

@ -30,6 +30,8 @@ const PopoverComponent: React.FC = () => {
event: undefined, event: undefined,
}); });
const [renderItem, setRenderItem] = useState(true);
return ( return (
<IonPage> <IonPage>
<IonContent> <IonContent>
@ -70,6 +72,12 @@ const PopoverComponent: React.FC = () => {
> >
Show Popover, hide after 250 ms Show Popover, hide after 250 ms
</IonButton> </IonButton>
{renderItem && <IonItem>
<IonButton id="openPopover">Open</IonButton>
<IonPopover id="popoverInItem" trigger="openPopover" dismissOnSelect={true}>
<IonButton id="removeItem" onClick={() => setRenderItem(false)}>Remove Item</IonButton>
</IonPopover>
</IonItem>}
</IonContent> </IonContent>
</IonPage> </IonPage>
); );