通常、コンポーネントのライフサイクルは、ビジネス ロジックが始まる場所です。 ビジネスシナリオが複雑でコンポーネントのライフサイクルが期待通りに機能しない場合は、 これにより、再現や修正が非常に難しい奇妙なビジネス バグが発生する可能性があります。 コンポーネント添付ライフサイクル実行時間一般的な理解によれば、複数回実行される可能性のある移動/表示/非表示のライフサイクルを除いて、 厳密に言えば、作成、アタッチ、準備完了などのコンポーネントの読み込みに関連するライフサイクルは、各コンポーネント インスタンスに対して 1 回だけ実行される必要があります。しかし、これは本当にそうなのでしょうか? 背景 この問題の発見は、ミニプログラムのエラー ログから得られました。 「プロパティ: isComponent を再定義できません」などのエラーが多数発生しました。 原因分析 変数名を通じて、コード内での定義方法を遡ることができます。 成分({ 生涯: 添付() { Object.defineProperty(this, 'isComponent', { 列挙可能: true、 get() { true を返す }, }); }, }, }); このエラーの原因は、オブジェクトの構成不可能なプロパティを再定義しようとしていることであることは容易に理解できます。 詳細については、MDN の説明を参照してください。 しかし、この定義は添付ライフサイクル内に記述されています。コンポーネントの添付ライフサイクルが 2 回トリガーされることを意味しますか? ああ、なんてことだ、どうしてこんなことが可能なのか? はい、それは魔法のようです! シーンの復元 この問題を再現するのは簡単ではありませんが、問題を継続的に単純化して解明することで、最終的に根本的な原因を見つけました。
このシナリオは次のコードで再現することも、アプレット コード スニペットに直接アクセスすることもできます。 ページ // ページ.js ページ({ データ: { 表示子2: false、 }, onChild1Attached() { this.setData({ showChild2: true }); }, }); <!-- page.wxml --> <child1 バインド:添付="onChild1Attached"></child1> <child2 wx:if="{{ showChild2 }}"></child2> サブコンポーネント 1 ページと一緒にレンダリングされ、アタッチされると、ページにステータスを更新し、triggerEvent を通じてサブコンポーネント 2 をレンダリングするように通知します。 //child1.js 成分({ 生涯: 添付() { this.triggerEvent('添付'); }, }, }); <!-- child1.wxml --> <view>子1</view> サブコンポーネント 2 添付されたライフサイクルが 2 回実行され、エラーが発生しました。 //child2.js 成分({ 生涯: 添付() { Object.defineProperty(this, 'isComponent', { 列挙可能: true、 get() { true を返す }, }); }, }, }); <!-- child2.wxml --> <view>子2</view> コンポーネント準備ライフサイクル実行時間ミニプログラムの公式ドキュメントでは、コンポーネントのライフサイクルの実行順序は明確に示されていませんが、ログを印刷することで簡単に確認できます。
したがって、順序は、作成済み -> アタッチ済み -> 準備完了 -> デタッチ済みである必要があるようです。 しかし、これは本当にそうなのでしょうか? 背景 一時期、当社のミニプログラムにデータの文字列化があるという報告がカスタマー サービスから頻繁にありました。 例: 販売者 A のライブ放送では、販売者 B の製品が紹介されます。 原因分析 文字列データは複数のシナリオで発生します。データがメッセージ経由でミニプログラムにプッシュされることを考慮すると、最終的には WebSocket 通信に問題があると疑われます。 ミニプログラム側では、WebSocket 通信コンポーネントをカプセル化します。コアロジックは次のとおりです。 // ソケット.js 成分({ 生涯: 準備ができて() { this.getSocketConfig().then(config => { this.ws = wx.connectSocket(config); this.ws.onMessage(メッセージ => { 定数データ = JSON.parse(msg.data); this.onReceiveMessage(データ); }); }); }, 切り離された() { this.ws && this.ws.close({}); }, }, メソッド: { getSocketConfig() { // サーバーにソケット接続構成を要求します。 return new Promise(() => {}); }, onReceiveMessage(データ) { イベント.emit('メッセージ', データ); }, }, }); 簡単に言うと、コンポーネントの準備が整うと、WebSocket 接続が初期化され、メッセージのプッシュがリッスンされ、その後、接続がデタッチ フェーズで閉じられます。 問題はないようですから、結果からは常識に沿わないかもしれない状況を推測することしかできません。 データの順序が正しくない -> WebSocket メッセージの順序が正しくない -> WebSocket が適切に閉じられていない -> close が間違っている/detached が実行されていない/detached 後に ready が実行される シーンの復元 ここでの実際のビジネス ロジックは比較的複雑なので、簡略化されたコードを通じてのみ検証できます。 継続的な実験を通じて、私たちは最終的に次のことを発見しました。
このシナリオは次のコードで再現することも、アプレット コード スニペットに直接アクセスすることもできます。 ページ // ページ.js ページ({ データ: { 表示子: true、 }, オンロード() { this.setData({ showChild: false }); }, }); <!-- page.wxml --> <child wx:if="{{ showChild }}" /> コンポーネント コンポーネントが準備ができていないときに破棄されると、まず detached が同期的に実行され、次に ready が非同期的に実行されます。 //child.js 成分({ 生涯: 作成された() { console.log('作成されました'); }, 添付() { console.log('添付'); }, 準備ができて() { console.log('準備完了'); }, 切り離された() { console.log('デタッチ'); } }, }); 拡大する 初期化作業が準備段階から接続段階に移動されたとしても、非同期操作がある限り、非同期コールバックの前にデタッチが実行される可能性があります。 したがって、コンポーネントのデタッチフェーズ中の破壊操作を完全に信頼しないでください。 要約するWeChatミニプログラムコンポーネントライフサイクルの落とし穴に関するこの記事はこれで終わりです。ミニプログラムコンポーネントライフサイクルに関するより関連性の高いコンテンツについては、123WORDPRESS.COMで以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も123WORDPRESS.COMを応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Linux でマウントされたファイルシステムの種類を表示する方法
>>: MySQL 5.1 のパスワードを変更し、MySQL データベースにリモートでログインする方法
目次製品要件アイデア問題ライブラリ選択をドラッグコンポーネントを生成する方法コンポーネントを生成する...
オーディオおよびビデオ ファイルを保存するためのディスク寿命を延ばすには、ディスクをフォーマットする...
序文私は Win7 を搭載した古いラップトップを持っています。古いシステムを維持しながら、同時に U...
React コンポーネントのライフサイクル機能とは何ですか?ライフサイクル関数は、ES6 構文クラス...
目次1. ルーティングとページジャンプ2. インターフェース要約する1. ルーティングとページジャン...
WeChatアプレットはスクロールビューを使用して左右のリンクを実現します。参考までに、具体的な内容...
目次ダーティページ(メモリページ)ダーティページが表示されるのはなぜですか?メモリ管理メカニズムの簡...
Mysql5.7.19バージョンは今年リリースされた新しいバージョンです。最近のMySQLのバージ...
目次1. 基本2. ノード、ツリー、仮想DOM 1. 仮想DOM 3. createElementパ...
Linux の優れた点は、マルチユーザー、マルチタスク システムにあります。 Linux では通常、...
1.1 nginxインストールパッケージとインストールスクリプトをクライアントにコピーし、スクリプト...
SSHとは何か管理者はリモートでログインして、インターネット経由で接続されたさまざまな場所にある複数...
目次【コード背景】 【コード実装】 #1# -> コード再利用の基本は、再利用可能なコンポーネ...
1. COUNT(*) と COUNT(COL) COUNT(*)は通常、主キーに対してインデックス...
Ubuntu 20.04は2020年4月に正式にリリースされました。本日、ミラーシステムを正式にイン...