質問編集履歴
2
文体の修正
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
|
|
121
121
|
もしライフサイクルを対称的にし、`unmount` の内部で `destroy` を呼び出す設計にした場合のコード例と、その利点・欠点について以下に示します。
|
|
122
122
|
|
|
123
|
-
ここで言う「対称性」とは、**「生成 (`mount`) が内部で `render` を呼び出す」**のに
|
|
123
|
+
ここで言う「対称性」とは、**「生成 (`mount`) が内部で `render` を呼び出す」**のと同様に、**「破棄 (`unmount`) が内部で `destroy` を呼び出す」**という構造を指します。
|
|
124
124
|
|
|
125
125
|
```javascript
|
|
126
126
|
class SymmetricComponent {
|
|
@@ -190,9 +190,8 @@
|
|
|
190
190
|
### 対称的ライフサイクルの利点と欠点
|
|
191
191
|
|
|
192
192
|
#### 利点
|
|
193
|
-
* **APIの単純化**: コンポーネントの利用者は `unmount` を呼べばすべてがクリーンアップされる、という単純なルールになり、`destroy` の呼び忘れを防ぐことができます。APIがシンプルで分かりやすくなります。
|
|
193
|
+
* **APIの単純化**: コンポーネントの利用者は `unmount` を呼べばすべてがクリーンアップされる、という単純なルールになり、`destroy` の呼び忘れを防ぐことができます。APIがシンプルで分かりやすくなります。(コンポーネントの利用者は `mount` と `unmount` という一対のメソッドのみを意識すればよくなります。)
|
|
194
194
|
|
|
195
195
|
#### 欠点
|
|
196
196
|
* **再利用性の喪失**: この設計の最大の欠点は、`unmount`(DOMからの切り離し)と `destroy`(内部状態の破棄)が密結合になることです。一度 `unmount` するとコンポーネントは完全に破棄されるため、「DOMから一時的に切り離し、後で再アタッチする」という再利用ができなくなります。
|
|
197
197
|
* **パフォーマンスへの影響**: 再利用ができないため、同じコンポーネントを再度表示したい場合は、常に新しいインスタンスを `new` から生成し直す必要があります。これは、特に頻繁に表示・非表示が切り替わるUIではパフォーマンスの低下につながります。
|
|
198
|
-
|
1
補足
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -113,3 +113,86 @@
|
|
|
113
113
|
2. この設計の妥当性は、主にコンポーネントの**パフォーマンスと再利用性**を高めるため、という認識で合っていますか?
|
|
114
114
|
|
|
115
115
|
専門家の方々のご意見を伺えますと幸いです。
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 補足: `unmount`と`destroy`を対称的にした場合
|
|
120
|
+
|
|
121
|
+
もしライフサイクルを対称的にし、`unmount` の内部で `destroy` を呼び出す設計にした場合のコード例と、その利点・欠点について以下に示します。
|
|
122
|
+
|
|
123
|
+
ここで言う「対称性」とは、**「生成 (`mount`) が内部で `render` を呼び出す」**のに対し、**「破棄 (`unmount`) が内部で `destroy` を呼び出す」**という構造を指します。これにより、コンポーネントの利用者は `mount` と `unmount` という一対のメソッドのみを意識すればよくなります。
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
class SymmetricComponent {
|
|
127
|
+
constructor() {
|
|
128
|
+
this.domNode = null;
|
|
129
|
+
this.subscriptions = [];
|
|
130
|
+
this.isMounted = false;
|
|
131
|
+
this.isDestroyed = false; // 破棄済みフラグ
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
render() {
|
|
135
|
+
const div = document.createElement('div');
|
|
136
|
+
div.textContent = 'Hello, Symmetric Component!';
|
|
137
|
+
this.domNode = div;
|
|
138
|
+
return this.domNode;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
mount(parentElement) {
|
|
142
|
+
if (this.isDestroyed) {
|
|
143
|
+
console.error("破棄済みのコンポーネントは mount できません。");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const elementToMount = this.render();
|
|
147
|
+
parentElement.appendChild(elementToMount);
|
|
148
|
+
this.isMounted = true;
|
|
149
|
+
this.subscriptions.push('subscription1');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// unmount が destroy を兼ねる
|
|
153
|
+
unmount() {
|
|
154
|
+
console.log("unmount: UIをDOMから取り除き、破棄処理を開始します...");
|
|
155
|
+
if (this.isMounted && this.domNode && this.domNode.parentElement) {
|
|
156
|
+
this.domNode.parentElement.removeChild(this.domNode);
|
|
157
|
+
this.isMounted = false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 自身の破棄処理を呼び出す
|
|
161
|
+
this.destroy();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
destroy() {
|
|
165
|
+
if (this.isDestroyed) {
|
|
166
|
+
return; // 二重解放を防ぐ
|
|
167
|
+
}
|
|
168
|
+
console.log("destroy: 全てのリソースを解放しています...");
|
|
169
|
+
|
|
170
|
+
// 全てのリソースをクリーンアップ
|
|
171
|
+
this.subscriptions = [];
|
|
172
|
+
this.domNode = null;
|
|
173
|
+
this.isDestroyed = true; // 破棄済みに設定
|
|
174
|
+
console.log("destroy: 完了。コンポーネントは完全に破棄されました。");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// --- 呼び出し元のコード ---
|
|
179
|
+
const symmComp = new SymmetricComponent();
|
|
180
|
+
const container = document.getElementById('app');
|
|
181
|
+
symmComp.mount(container);
|
|
182
|
+
|
|
183
|
+
// --- 破棄フェーズ ---
|
|
184
|
+
// unmountを呼ぶだけで、destroyも実行される
|
|
185
|
+
symmComp.unmount();
|
|
186
|
+
|
|
187
|
+
// この後、symmComp.mount(container) を呼び出しても再利用はできない
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 対称的ライフサイクルの利点と欠点
|
|
191
|
+
|
|
192
|
+
#### 利点
|
|
193
|
+
* **APIの単純化**: コンポーネントの利用者は `unmount` を呼べばすべてがクリーンアップされる、という単純なルールになり、`destroy` の呼び忘れを防ぐことができます。APIがシンプルで分かりやすくなります。
|
|
194
|
+
|
|
195
|
+
#### 欠点
|
|
196
|
+
* **再利用性の喪失**: この設計の最大の欠点は、`unmount`(DOMからの切り離し)と `destroy`(内部状態の破棄)が密結合になることです。一度 `unmount` するとコンポーネントは完全に破棄されるため、「DOMから一時的に切り離し、後で再アタッチする」という再利用ができなくなります。
|
|
197
|
+
* **パフォーマンスへの影響**: 再利用ができないため、同じコンポーネントを再度表示したい場合は、常に新しいインスタンスを `new` から生成し直す必要があります。これは、特に頻繁に表示・非表示が切り替わるUIではパフォーマンスの低下につながります。
|
|
198
|
+
|