Skip to main content

React 生命周期

本指南讨论如何在 Ionic React 应用中使用 Ionic Lifecycle 事件。

¥This guide discusses how to use the Ionic Lifecycle events in an Ionic React application.

Ionic 生命周期方法

¥Ionic Lifecycle Methods

Ionic 提供了一些可以在应用中使用的生命周期方法:

¥Ionic provides a few lifecycle methods that you can use in your apps:

活动名称描述
ionViewWillEnter当组件路由即将动画进入视图时触发。
ionViewDidEnter当组件路由完成动画时触发。
ionViewWillLeave当组件路由即将动画时触发。
ionViewDidLeave当组件路由完成动画时触发。

这些生命周期仅在由路由直接映射的组件上调用。这意味着如果 /pageOne 映射到 PageOneComponent,则 Ionic 生命周期将在 PageOneComponent 上调用,但不会在 PageOneComponent 可能渲染的任何子组件上调用。

¥These lifecycles are only called on components directly mapped by a router. This means if /pageOne maps to PageOneComponent, then Ionic lifecycles will be called on PageOneComponent but will not be called on any child components that PageOneComponent may render.

访问这些方法的方式根据你使用的是基于类的组件还是函数式组件而有所不同。我们将在下面介绍这两种方法。

¥The way you access these methods varies based on if you are using class-based components or functional components. We cover both methods below.

基于类的组件中的生命周期方法

¥Lifecycle Methods in Class-Based Components

要在基于类的组件中使用 Ionic Lifecycle 方法,你必须使用 withIonLifeCycle 高阶组件 (HOC) 封装组件,如下所示:

¥to use the Ionic Lifecycle methods in a class-based component, you must wrap your component with the withIonLifeCycle higher order component (HOC) like so:

export default withIonLifeCycle(HomePage);
注意

withIonLifeCycle 是从 @ionic/react 导入的

¥withIonLifeCycle is imported from @ionic/react

然后,你可以在类组件上创建适当的生命周期方法,并且 HOC 在事件发生时调用该方法。下面是实现了每个生命周期方法的整个组件:

¥You can then create the appropriate lifecycle method on your class component, and the HOC calls that method when the event happens. Below is the entire component with each of the lifecycle methods implemented:

import React from 'react';


import { IonHeader, IonPage, IonToolbar, IonTitle, IonContent, withIonLifeCycle } from '@ionic/react';



class HomePage extends React.Component {
ionViewWillEnter() {
console.log('ionViewWillEnter event fired');
}

ionViewWillLeave() {
console.log('ionViewWillLeave event fired');
}

ionViewDidEnter() {
console.log('ionViewDidEnter event fired');
}

ionViewDidLeave() {
console.log('ionViewDidLeave event fired');
}

render() {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Home</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent></IonContent>
</IonPage>
);
}
}

export default withIonLifeCycle(HomePage);

功能组件中的生命周期方法

¥Lifecycle Methods in Functional Components

Ionic React 为你可以在功能组件中使用的每个生命周期方法导出钩子。每个钩子都采用你想要在事件触发时调用的方法。

¥Ionic React exports hooks for each of the lifecycle methods that you can use in your functional components. Each of the hooks takes the method you want called when the event fires.

import {
IonContent,
IonHeader,
IonTitle,
IonToolbar,
useIonViewDidEnter,
useIonViewDidLeave,
useIonViewWillEnter,
useIonViewWillLeave,
} from '@ionic/react';
import React from 'react';

const HomePage: React.FC = () => {
useIonViewDidEnter(() => {
console.log('ionViewDidEnter event fired');
});

useIonViewDidLeave(() => {
console.log('ionViewDidLeave event fired');
});

useIonViewWillEnter(() => {
console.log('ionViewWillEnter event fired');
});

useIonViewWillLeave(() => {
console.log('ionViewWillLeave event fired');
});

return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Home</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent></IonContent>
</IonPage>
);
};

export default HomePage;
注意

功能组件不需要像类组件那样用 withIonLifeCycle HOC 封装。

¥Functional components don't need to be wrapped with the withIonLifeCycle HOC as class components do.

开发者还可以选择将反应性依赖传递给每个生命周期钩子。然后将它们传递给底层 React useEffect 钩子

¥Developers can also optionally pass reactive dependencies to each lifecycle hook. These are then passed to the underlying React useEffect hook:

const [data, setData] = useState('foo');

useIonViewDidEnter(() => {
console.log('ionViewDidEnter event fired');
}, [data]);

React 生命周期方法

¥React LifeCycle Methods

React 中的所有生命周期方法(componentDidMountcomponentWillUnmount 等)也可供你使用。然而,由于 Ionic React 管理页面的生命周期,某些事件可能不会在你期望的时候触发。例如,第一次显示页面时 componentDidMount 会触发,但如果你离开该页面,Ionic 可能会将该页面保留在 DOM 中,并且后续访问该页面可能不会再次调用 componentDidMount。这种情况是 Ionic 生命周期方法存在的主要原因,当原生框架的事件可能不会触发时,仍然为你提供了一种在视图进入和退出时调用逻辑的方法。

¥All the lifecycle methods in React (componentDidMount, componentWillUnmount, etc..) are available for you to use as well. However, since Ionic React manages the lifetime of a page, certain events might not fire when you expect them to. For instance, componentDidMount fires the first time a page is displayed, but if you navigate away from the page Ionic might keep the page around in the DOM, and a subsequent visit to the page might not call componentDidMount again. This scenario is the main reason the Ionic lifecycle methods exist, to still give you a way to call logic when views enter and exit when the native framework's events might not fire.

每种生命周期方法的指南

¥Guidance for Each LifeCycle Method

以下是有关每个生命周期事件用例的一些提示。

¥Below are some tips on use cases for each of the life cycle events.

  • ionViewWillEnter - 由于每次导航到视图时都会调用 ionViewWillEnter(无论是否初始化),因此这是从服务加载数据的好方法。

    ¥ionViewWillEnter - Since ionViewWillEnter is called every time the view is navigated to (regardless if initialized or not), it's a good method to load data from services.

  • ionViewDidEnter - 如果你在加载数据时发现使用 ionViewWillEnter 存在性能问题,则可以改为在 ionViewDidEnter 中进行数据调用。但是,直到用户看到页面后才会触发此事件,因此你可能需要使用加载指示器或框架屏幕,以便内容在转换完成后不会不自然地闪烁。

    ¥ionViewDidEnter - If you see performance problems from using ionViewWillEnter when loading data, you can do your data calls in ionViewDidEnter instead. This event won't fire until after the page is visible to the user, however, so you might want to use either a loading indicator or a skeleton screen, so content doesn't flash in un-naturally after the transition is complete.

  • ionViewWillLeave - 可用于清理,例如取消订阅数据源。由于从当前页面导航时 componentWillUnmount 可能不会触发,因此如果你不希望在屏幕未显示时激活清理代码,请将清理代码放在这里。

    ¥ionViewWillLeave - Can be used for cleanup, like unsubscribing from data sources. Since componentWillUnmount might not fire when you navigate from the current page, put your cleanup code here if you don't want it active while the screen is not in view.

  • ionViewDidLeave - 当此事件触发时,你知道新页面已完全转换,因此当视图可见时你通常不会执行的任何逻辑都可以转到此处。

    ¥ionViewDidLeave - When this event fires, you know the new page has fully transitioned in, so any logic you might not normally do when the view is visible can go here.

在页面之间传递状态

¥Passing state between pages

由于 Ionic React 管理页面的生命周期,因此当用户导航你的应用时,先前页面上的状态可能会更新。这可能会影响使用 React 中的 useEffect 或 React Router 中的 useLocation 确定的状态。例如,如果 PageA 调用 useLocation,则当用户从 PageA 导航到 PageB 时,useLocation 的状态将会改变。

¥Since Ionic React manages the lifetime of a page, state on previous pages may update as users navigate your application. This can impact state that is determined using useEffect from React or useLocation from React Router. For example, if PageA calls useLocation, the state of useLocation will change when the user navigates from PageA to PageB.

开发者应进行适当的检查,以确保先前的页面仅访问定义的状态。

¥Developers should include the appropriate checks to ensure that previous pages only access defined states.

例如,如果未定义 testObject,以下代码将出错:{ state.testObject.childKey }

¥For example, the following code will error if testObject is not defined: { state.testObject.childKey }

相反,开发者应仅在定义了 testObject 时才访问 childKey{ state.testObject?.childKey }

¥Instead, developers should access childKey only if testObject is defined: { state.testObject?.childKey }