@ionic/react 7.5.1-dev.11697123035.1ee6b4a2 → 7.5.1-dev.11697212309.1448948d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -113,6 +113,18 @@ const IonLifeCycleContext = /*@__PURE__*/ React.createContext({
113
113
  ionViewDidLeave: () => {
114
114
  return;
115
115
  },
116
+ cleanupIonViewWillEnter: () => {
117
+ return;
118
+ },
119
+ cleanupIonViewDidEnter: () => {
120
+ return;
121
+ },
122
+ cleanupIonViewWillLeave: () => {
123
+ return;
124
+ },
125
+ cleanupIonViewDidLeave: () => {
126
+ return;
127
+ },
116
128
  });
117
129
  const DefaultIonLifeCycleContext = class {
118
130
  constructor() {
@@ -120,6 +132,10 @@ const DefaultIonLifeCycleContext = class {
120
132
  this.ionViewDidEnterCallbacks = [];
121
133
  this.ionViewWillLeaveCallbacks = [];
122
134
  this.ionViewDidLeaveCallbacks = [];
135
+ this.ionViewWillEnterDestructorCallbacks = [];
136
+ this.ionViewDidEnterDestructorCallbacks = [];
137
+ this.ionViewWillLeaveDestructorCallbacks = [];
138
+ this.ionViewDidLeaveDestructorCallbacks = [];
123
139
  }
124
140
  onIonViewWillEnter(callback) {
125
141
  if (callback.id) {
@@ -135,8 +151,59 @@ const DefaultIonLifeCycleContext = class {
135
151
  this.ionViewWillEnterCallbacks.push(callback);
136
152
  }
137
153
  }
154
+ teardownCallback(callback, callbacks) {
155
+ // Find any destructors that have been registered for the callback
156
+ const matches = callbacks.filter((x) => x.id === callback.id);
157
+ if (matches.length !== 0) {
158
+ // Execute the destructor for each matching item
159
+ matches.forEach((match) => {
160
+ if (match && typeof match.destructor === 'function') {
161
+ match.destructor();
162
+ }
163
+ });
164
+ // Remove all matching items from the array
165
+ callbacks = callbacks.filter((x) => x.id !== callback.id);
166
+ }
167
+ }
168
+ /**
169
+ * Tears down the user-provided ionViewWillEnter lifecycle callback.
170
+ * This is the same behavior as React's useEffect hook. The callback
171
+ * is invoked when the component is unmounted.
172
+ */
173
+ cleanupIonViewWillEnter(callback) {
174
+ this.teardownCallback(callback, this.ionViewWillEnterDestructorCallbacks);
175
+ }
176
+ /**
177
+ * Tears down the user-provided ionViewDidEnter lifecycle callback.
178
+ * This is the same behavior as React's useEffect hook. The callback
179
+ * is invoked when the component is unmounted.
180
+ */
181
+ cleanupIonViewDidEnter(callback) {
182
+ this.teardownCallback(callback, this.ionViewDidEnterDestructorCallbacks);
183
+ }
184
+ /**
185
+ * Tears down the user-provided ionViewWillLeave lifecycle callback.
186
+ * This is the same behavior as React's useEffect hook. The callback
187
+ * is invoked when the component is unmounted.
188
+ */
189
+ cleanupIonViewWillLeave(callback) {
190
+ this.teardownCallback(callback, this.ionViewWillLeaveDestructorCallbacks);
191
+ }
192
+ /**
193
+ * Tears down the user-provided ionViewDidLeave lifecycle callback.
194
+ * This is the same behavior as React's useEffect hook. The callback
195
+ * is invoked when the component is unmounted.
196
+ */
197
+ cleanupIonViewDidLeave(callback) {
198
+ this.teardownCallback(callback, this.ionViewDidLeaveDestructorCallbacks);
199
+ }
138
200
  ionViewWillEnter() {
139
- this.ionViewWillEnterCallbacks.forEach((cb) => cb());
201
+ this.ionViewWillEnterCallbacks.forEach((cb) => {
202
+ const destructor = cb();
203
+ if (cb.id) {
204
+ this.ionViewWillEnterDestructorCallbacks.push({ id: cb.id, destructor });
205
+ }
206
+ });
140
207
  }
141
208
  onIonViewDidEnter(callback) {
142
209
  if (callback.id) {
@@ -153,7 +220,12 @@ const DefaultIonLifeCycleContext = class {
153
220
  }
154
221
  }
155
222
  ionViewDidEnter() {
156
- this.ionViewDidEnterCallbacks.forEach((cb) => cb());
223
+ this.ionViewDidEnterCallbacks.forEach((cb) => {
224
+ const destructor = cb();
225
+ if (cb.id) {
226
+ this.ionViewDidEnterDestructorCallbacks.push({ id: cb.id, destructor });
227
+ }
228
+ });
157
229
  }
158
230
  onIonViewWillLeave(callback) {
159
231
  if (callback.id) {
@@ -170,7 +242,12 @@ const DefaultIonLifeCycleContext = class {
170
242
  }
171
243
  }
172
244
  ionViewWillLeave() {
173
- this.ionViewWillLeaveCallbacks.forEach((cb) => cb());
245
+ this.ionViewWillLeaveCallbacks.forEach((cb) => {
246
+ const destructor = cb();
247
+ if (cb.id) {
248
+ this.ionViewWillLeaveDestructorCallbacks.push({ id: cb.id, destructor });
249
+ }
250
+ });
174
251
  }
175
252
  onIonViewDidLeave(callback) {
176
253
  if (callback.id) {
@@ -187,7 +264,12 @@ const DefaultIonLifeCycleContext = class {
187
264
  }
188
265
  }
189
266
  ionViewDidLeave() {
190
- this.ionViewDidLeaveCallbacks.forEach((cb) => cb());
267
+ this.ionViewDidLeaveCallbacks.forEach((cb) => {
268
+ const destructor = cb();
269
+ if (cb.id) {
270
+ this.ionViewDidLeaveDestructorCallbacks.push({ id: cb.id, destructor });
271
+ }
272
+ });
191
273
  this.componentCanBeDestroyed();
192
274
  }
193
275
  onComponentCanBeDestroyed(callback) {
@@ -246,6 +328,9 @@ const useIonViewWillEnter = (callback, deps = []) => {
246
328
  useEffect(() => {
247
329
  callback.id = id.current;
248
330
  context.onIonViewWillEnter(callback);
331
+ return () => {
332
+ context.cleanupIonViewWillEnter(callback);
333
+ };
249
334
  }, deps);
250
335
  };
251
336
  const useIonViewDidEnter = (callback, deps = []) => {
@@ -255,6 +340,9 @@ const useIonViewDidEnter = (callback, deps = []) => {
255
340
  useEffect(() => {
256
341
  callback.id = id.current;
257
342
  context.onIonViewDidEnter(callback);
343
+ return () => {
344
+ context.cleanupIonViewDidEnter(callback);
345
+ };
258
346
  }, deps);
259
347
  };
260
348
  const useIonViewWillLeave = (callback, deps = []) => {
@@ -264,6 +352,9 @@ const useIonViewWillLeave = (callback, deps = []) => {
264
352
  useEffect(() => {
265
353
  callback.id = id.current;
266
354
  context.onIonViewWillLeave(callback);
355
+ return () => {
356
+ context.cleanupIonViewWillLeave(callback);
357
+ };
267
358
  }, deps);
268
359
  };
269
360
  const useIonViewDidLeave = (callback, deps = []) => {
@@ -273,6 +364,9 @@ const useIonViewDidLeave = (callback, deps = []) => {
273
364
  useEffect(() => {
274
365
  callback.id = id.current;
275
366
  context.onIonViewDidLeave(callback);
367
+ return () => {
368
+ context.cleanupIonViewDidLeave(callback);
369
+ };
276
370
  }, deps);
277
371
  };
278
372
 
@@ -1020,6 +1114,16 @@ class PageManager extends React.PureComponent {
1020
1114
  this.ionPageElementRef = React.createRef();
1021
1115
  // React refs must be stable (not created inline).
1022
1116
  this.stableMergedRefs = mergeRefs(this.ionPageElementRef, this.props.forwardedRef);
1117
+ /**
1118
+ * This binds the scope of the following methods to the class scope.
1119
+ * The `.bind` method returns a new function, so we need to assign it
1120
+ * in the constructor rather than when adding or removing the listeners
1121
+ * to avoid creating a new function.
1122
+ */
1123
+ this.ionViewWillEnterHandler = this.ionViewWillEnterHandler.bind(this);
1124
+ this.ionViewDidEnterHandler = this.ionViewDidEnterHandler.bind(this);
1125
+ this.ionViewWillLeaveHandler = this.ionViewWillLeaveHandler.bind(this);
1126
+ this.ionViewDidLeaveHandler = this.ionViewDidLeaveHandler.bind(this);
1023
1127
  }
1024
1128
  componentDidMount() {
1025
1129
  if (this.ionPageElementRef.current) {
@@ -1027,18 +1131,18 @@ class PageManager extends React.PureComponent {
1027
1131
  this.ionPageElementRef.current.classList.add('ion-page-invisible');
1028
1132
  }
1029
1133
  this.context.registerIonPage(this.ionPageElementRef.current, this.props.routeInfo);
1030
- this.ionPageElementRef.current.addEventListener('ionViewWillEnter', this.ionViewWillEnterHandler.bind(this));
1031
- this.ionPageElementRef.current.addEventListener('ionViewDidEnter', this.ionViewDidEnterHandler.bind(this));
1032
- this.ionPageElementRef.current.addEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler.bind(this));
1033
- this.ionPageElementRef.current.addEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler.bind(this));
1134
+ this.ionPageElementRef.current.addEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
1135
+ this.ionPageElementRef.current.addEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
1136
+ this.ionPageElementRef.current.addEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler);
1137
+ this.ionPageElementRef.current.addEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler);
1034
1138
  }
1035
1139
  }
1036
1140
  componentWillUnmount() {
1037
1141
  if (this.ionPageElementRef.current) {
1038
- this.ionPageElementRef.current.removeEventListener('ionViewWillEnter', this.ionViewWillEnterHandler.bind(this));
1039
- this.ionPageElementRef.current.removeEventListener('ionViewDidEnter', this.ionViewDidEnterHandler.bind(this));
1040
- this.ionPageElementRef.current.removeEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler.bind(this));
1041
- this.ionPageElementRef.current.removeEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler.bind(this));
1142
+ this.ionPageElementRef.current.removeEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
1143
+ this.ionPageElementRef.current.removeEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
1144
+ this.ionPageElementRef.current.removeEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler);
1145
+ this.ionPageElementRef.current.removeEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler);
1042
1146
  }
1043
1147
  }
1044
1148
  ionViewWillEnterHandler() {
@@ -1147,6 +1251,16 @@ class OutletPageManager extends React.Component {
1147
1251
  constructor(props) {
1148
1252
  super(props);
1149
1253
  this.outletIsReady = false;
1254
+ /**
1255
+ * This binds the scope of the following methods to the class scope.
1256
+ * The `.bind` method returns a new function, so we need to assign it
1257
+ * in the constructor rather than when adding or removing the listeners
1258
+ * to avoid creating a new function.
1259
+ */
1260
+ this.ionViewWillEnterHandler = this.ionViewWillEnterHandler.bind(this);
1261
+ this.ionViewDidEnterHandler = this.ionViewDidEnterHandler.bind(this);
1262
+ this.ionViewWillLeaveHandler = this.ionViewWillLeaveHandler.bind(this);
1263
+ this.ionViewDidLeaveHandler = this.ionViewDidLeaveHandler.bind(this);
1150
1264
  }
1151
1265
  componentDidMount() {
1152
1266
  if (this.ionRouterOutlet) {
@@ -1160,18 +1274,18 @@ class OutletPageManager extends React.Component {
1160
1274
  this.context.registerIonPage(this.ionRouterOutlet, this.props.routeInfo);
1161
1275
  });
1162
1276
  }
1163
- this.ionRouterOutlet.addEventListener('ionViewWillEnter', this.ionViewWillEnterHandler.bind(this));
1164
- this.ionRouterOutlet.addEventListener('ionViewDidEnter', this.ionViewDidEnterHandler.bind(this));
1165
- this.ionRouterOutlet.addEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler.bind(this));
1166
- this.ionRouterOutlet.addEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler.bind(this));
1277
+ this.ionRouterOutlet.addEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
1278
+ this.ionRouterOutlet.addEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
1279
+ this.ionRouterOutlet.addEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler);
1280
+ this.ionRouterOutlet.addEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler);
1167
1281
  }
1168
1282
  }
1169
1283
  componentWillUnmount() {
1170
1284
  if (this.ionRouterOutlet) {
1171
- this.ionRouterOutlet.removeEventListener('ionViewWillEnter', this.ionViewWillEnterHandler.bind(this));
1172
- this.ionRouterOutlet.removeEventListener('ionViewDidEnter', this.ionViewDidEnterHandler.bind(this));
1173
- this.ionRouterOutlet.removeEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler.bind(this));
1174
- this.ionRouterOutlet.removeEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler.bind(this));
1285
+ this.ionRouterOutlet.removeEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
1286
+ this.ionRouterOutlet.removeEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
1287
+ this.ionRouterOutlet.removeEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler);
1288
+ this.ionRouterOutlet.removeEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler);
1175
1289
  }
1176
1290
  }
1177
1291
  ionViewWillEnterHandler() {