状態管理
状態とは何か
ofa.jsでは、状態とは、コンポーネントまたはページモジュール自身の data プロパティのことを指します。この状態は現在のコンポーネント上でのみ使用でき、当該コンポーネントの内部データを保存・管理します。
複数のコンポーネントやページで同じデータを共有する必要がある場合、従来の方法ではイベントの伝搬やpropsを階層的に渡していましたが、この方法は複雑なアプリケーションではコードの保守が困難になります。そのため、状態管理が必要となります――共有される状態オブジェクトを定義し、複数のコンポーネントやページモジュールがそのデータにアクセス・変更できるようにすることで、状態の共有を実現します。
ヒント:状態管理は、ユーザー情報、ショッピングカート、テーマ設定、グローバル設定など、コンポーネントやページをまたいでデータを共有する必要があるシナリオに適しています。
ステータスオブジェクトの生成
$.stanz({}) を使ってリアクティブな状態オブジェクトを作成します。このメソッドは、通常のオブジェクトを初期データとして受け取り、リアクティブな状態プロキシを返します。
基本的な使い方
// アプリケーションのホームページアドレス
export const home = "./list.html";
// ページ切り替えアニメーション設定
export const pageAnime = {
current: {
opacity: 1,
transform: "translate(0, 0)",
},
next: {
opacity: 0,
transform: "translate(30px, 0)",
},
previous: {
opacity: 0,
transform: "translate(-30px, 0)",
},
};
export const contacts = $.stanz({
list: [{
id: 10010,
name: "ピート",
info: "毎日が新しい始まり、雨の後には必ず太陽が輝く。",
},{
id: 10020,
name: "マイク",
info: "人生は海のようで、意志の強い人だけが対岸にたどり着ける。",
},{
id: 10030,
name: "ジョン",
info: "成功の秘訣は自分の夢を諦めずに貫き通すことにある。",
}]
});
// await fetch("/list.api").then(e=>e.json()).then(list=>data.list = list)
アドレス帳
-
名前: {{$data.name}}
状態オブジェクトの特性
1. レスポンシブ更新
$.stanz() で作成された状態オブジェクトはリアクティブです。状態データが変更されたとき、そのデータを参照するすべてのコンポーネントは自動的に更新されます。
const store = $.stanz({ count: 0 });
// コンポーネント内
export default {
data: {
store: {}
},
proto:{
increment() {
store.count++; // store.count を参照しているすべてのコンポーネントが自動的に更新される
}
},
attached() {
// 状態オブジェクトのプロパティを直接参照
this.store = store;
},
detached(){
this.store = {}; // コンポーネントが破棄される際、マウントされた状態データをクリア
}
};
2. ディープリアクティビティ
ステートオブジェクトは深いリアクティビティをサポートしており、ネストされたオブジェクトや配列の変更も監視されます。
const store = $.stanz({
user: {
name: "张三",
settings: {
theme: "dark"
}
},
list: []
});
// ネストされたプロパティの変更も更新をトリガーする
store.user.name = "李四";
store.user.settings.theme = "light";
store.list.push({ id: 1, title: "新しいタスク" });
ベストプラクティス
1. コンポーネントのattached段階でステータスをマウントする
コンポーネントのattachedライフサイクルで共有状態をマウントすることをお勧めします:
export default {
data: {
list: []
},
attached() {
// 共有状態をコンポーネントの data にマウントする
this.list = data.list;
},
detached() {
// コンポーネント破棄時、マウントされた状態データをクリアし、メモリリークを防ぐ
this.list = [];
}
};
2. 状態のスコープを合理的に管理する
- グローバル状態:アプリ全体からアクセスする必要があるデータ(ユーザー情報、グローバル設定など)に適用
- モジュール状態:特定の機能モジュール内で共有するデータに適用
// グローバル呼び出し状態
export const globalStore = $.stanz({ user: null, theme: "light" });
// モジュール内で使用する状態
const cartStore = $.stanz({ total: 0 });
モジュール内状態管理
{{$index}} -
{{val}} - {{cartStore.total}}
注意事項
-
状態のクリーンアップ:コンポーネントの
detachedライフサイクルにおいて、状態データへの参照をタイムリーにクリーンアップし、メモリリークを回避する。 -
循環依存を避ける:状態オブジェクト間で循環参照を形成しないようにし、これがリアクティブシステムに問題を引き起こす可能性がある。
-
大規模なデータ構造:大規模なデータ構造については、算出プロパティや分割管理を検討し、不要なパフォーマンスオーバーヘッドを回避する。
-
状態の一貫性:非同期操作において状態の一貫性に注意し、トランザクションやバッチ更新を使用してデータの整合性を保証できる。