mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 10:41:13 +08:00
fix(react): present controller overlays in React 18 (#25361)
Resolves #25247
This commit is contained in:
@ -1,7 +1,12 @@
|
|||||||
import { OverlayEventDetail } from '@ionic/core/components';
|
import { OverlayEventDetail } from '@ionic/core/components';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { attachProps, dashToPascalCase, defineCustomElement, setRef } from './react-component-lib/utils';
|
import {
|
||||||
|
attachProps,
|
||||||
|
dashToPascalCase,
|
||||||
|
defineCustomElement,
|
||||||
|
setRef,
|
||||||
|
} from './react-component-lib/utils';
|
||||||
|
|
||||||
interface OverlayBase extends HTMLElement {
|
interface OverlayBase extends HTMLElement {
|
||||||
present: () => Promise<void>;
|
present: () => Promise<void>;
|
||||||
@ -39,7 +44,7 @@ export const createControllerComponent = <
|
|||||||
|
|
||||||
class Overlay extends React.Component<Props> {
|
class Overlay extends React.Component<Props> {
|
||||||
overlay?: OverlayType;
|
overlay?: OverlayType;
|
||||||
isUnmounted = false;
|
willUnmount = false;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -51,6 +56,14 @@ export const createControllerComponent = <
|
|||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
/**
|
||||||
|
* Starting in React v18, strict mode will unmount and remount a component.
|
||||||
|
* See: https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors
|
||||||
|
*
|
||||||
|
* We need to reset this flag when the component is re-mounted so that
|
||||||
|
* overlay.present() will be called and the overlay will display.
|
||||||
|
*/
|
||||||
|
this.willUnmount = false;
|
||||||
const { isOpen } = this.props;
|
const { isOpen } = this.props;
|
||||||
if (isOpen as boolean) {
|
if (isOpen as boolean) {
|
||||||
this.present();
|
this.present();
|
||||||
@ -58,7 +71,7 @@ export const createControllerComponent = <
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.isUnmounted = true;
|
this.willUnmount = true;
|
||||||
if (this.overlay) {
|
if (this.overlay) {
|
||||||
this.overlay.dismiss();
|
this.overlay.dismiss();
|
||||||
}
|
}
|
||||||
@ -77,18 +90,17 @@ export const createControllerComponent = <
|
|||||||
if (this.props.onDidDismiss) {
|
if (this.props.onDidDismiss) {
|
||||||
this.props.onDidDismiss(event);
|
this.props.onDidDismiss(event);
|
||||||
}
|
}
|
||||||
setRef(this.props.forwardedRef, null)
|
setRef(this.props.forwardedRef, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
async present(prevProps?: Props) {
|
async present(prevProps?: Props) {
|
||||||
const {
|
const { isOpen, onDidDismiss, onDidPresent, onWillDismiss, onWillPresent, ...cProps } =
|
||||||
isOpen,
|
this.props;
|
||||||
onDidDismiss,
|
|
||||||
onDidPresent,
|
if (this.overlay) {
|
||||||
onWillDismiss,
|
this.overlay.remove();
|
||||||
onWillPresent,
|
}
|
||||||
...cProps
|
|
||||||
} = this.props;
|
|
||||||
this.overlay = await controller.create({
|
this.overlay = await controller.create({
|
||||||
...(cProps as any),
|
...(cProps as any),
|
||||||
});
|
});
|
||||||
@ -107,8 +119,8 @@ export const createControllerComponent = <
|
|||||||
);
|
);
|
||||||
// Check isOpen again since the value could have changed during the async call to controller.create
|
// Check isOpen again since the value could have changed during the async call to controller.create
|
||||||
// It's also possible for the component to have become unmounted.
|
// It's also possible for the component to have become unmounted.
|
||||||
if (this.props.isOpen === true && this.isUnmounted === false) {
|
if (this.props.isOpen === true && this.willUnmount === false) {
|
||||||
setRef(this.props.forwardedRef, this.overlay)
|
setRef(this.props.forwardedRef, this.overlay);
|
||||||
await this.overlay.present();
|
await this.overlay.present();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user