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.
*/
this.ref.current?.addEventListener('didDismiss', (evt: any) => {
const wrapper = this.wrapperRef.current!;
this.ref.current!.append(wrapper);
const wrapper = this.wrapperRef.current;
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);
});

View File

@ -18,4 +18,12 @@ describe('IonPopover', () => {
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,
});
const [renderItem, setRenderItem] = useState(true);
return (
<IonPage>
<IonContent>
@ -70,6 +72,12 @@ const PopoverComponent: React.FC = () => {
>
Show Popover, hide after 250 ms
</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>
</IonPage>
);