ネイティブWeChatアプレット開発におけるreduxの使用の詳細な説明

ネイティブWeChatアプレット開発におけるreduxの使用の詳細な説明

前提

複雑なシナリオでは、複数の異なるページ間で大量のデータを使用したり変更したりする必要があります。しかし、ミニプログラムページの直接データ通信方法は非常にシンプルです。通常、共通データを保存するにはグローバル オブジェクトを維持する必要があります。ただし、ビジネス ロジックが複雑になるにつれて、共有データ エンティティを単純に維持するだけでは規模が大きくなりすぎ、データの変更を適切に追跡できなくなることがよくあります。さらに、パブリック データ エンティティのデータの変更とページの UI の間には適切な同期方法がありません。ページと対応するデータ エンティティの両方で同じデータを維持する必要があることが多く、非常に不便です。

Taroは、これまでreact+reduxの構造を持つWeChatアプレットの開発に使用されていました。reduxに頼ることで、上記の問題を全体的に解決できます。しかし、太郎自体にも、受け入れがたい潜在的な問題がいくつかあります。ネイティブのライブラリを使用できる場合は、サードパーティの再パッケージ化されたライブラリを決して使用しないという原則に従います。私はずっと、ネイティブ WeChat アプレットの開発に redux を統合したいと思っていました。

解決すべき問題

1. reduxライブラリへのアクセス
2. ページUIとreduxデータのバインディング

reduxライブラリの紹介

1. redux をインストールするには、npm または yarn を使用できます。
具体的なreduxの中国公式ウェブサイトは次のとおりです:https://www.reduxjs.cn/introduction/getting-started/
2. WeChat アプレットは外部 npm パッケージを導入します。
WeChat Mini Program IDEA を使用し、ツールで npm をビルドして、miniprogram_npm を生成します。

3. エラー ReferenceError の解決方法: プロセスが redux ライブラリで定義されていません。

WeChat アプレットは npm ツールで構築されるため、構築中に nodeprocess 環境変数は導入されませんが、redux はさまざまな環境に対応する最適化を行っています。その結果、ビルドされたパッケージにはプロセス変数が不足しています。最も便利な解決策は、ビルドされたパッケージに必要なプロセスを自分で挿入することです。

これにより、基本的に、すべてのサードパーティ ライブラリで発生するプロセス パラメータの欠落の問題を解決できます。 Build npm ツールを実行するたびに手動で変更する必要がある場合。手動で変更する必要があるサードパーティライブラリが複数ある場合は面倒です。そのため、動的な変更を完了し、人件費を節約するためには、スクリプトやASTツリーなどのツールを使用する必要があります(これについては後で紹介します)

まとめると、redux の導入は完了です。

プロジェクトにreduxを追加する

1. ストアの作成

異なるエンティティをマージするには combineReducers を使用し、ストア エンティティを作成するには createStore を使用し、エクスポートします。データの統一性を保つために、Redux の原則では、プロジェクトは 1 つのストアのみを初期化し、後続の操作は現在生成されているストアで実行されます。

データ エンティティをマージします。

const { combineReducers } = require('redux');
const testItem = require('./testItem/index');
const testItem2 = require('./testItem2/index');
定数user = require('./user/index');

定数リデューサー = 結合リデューサー({
 テスト項目: テスト項目.テスト項目、
 テスト項目2、
 ユーザー
});

モジュール.エクスポート = {
 減速機
}

ストアをエクスポートします:

const { createStore、applyMiddleware } = require('redux');
const { リデューサー } = require('./reducers');
const { logger } = require('redux-logger');

const ストア = createStore(
 減速機、
 ミドルウェアを適用(ロガー)
)

モジュール.エクスポート = {
 店
}

2. グローバルメンテナンスストア

ここでの使用法は react の場合とは異なります。 WeChatアプレットにはストアをグローバルに維持するための対応するコントロールがないため、私のアプローチはapp.jsのglobalDataで直接維持し、各ページが直接ストアを取得できるようにすることです。
アプリ.js:

const { store } = require('./redux/index');

//アプリ.js
アプリ({
 グローバルデータ: {
  $store: ストア、
  getState: ()=> store.getState(),
 }
})

接続方法をシミュレートする

Reactでは、connectメソッドは高階コンポーネントを通じて実装されますが、このメソッドはWeChatアプレットには適用できません。幸いなことに、redux はストア内のデータの変更を監視するための subscribe メソッドを提供します。最初の設計は次のようになります。
1. ページに入るか表示されるたびにリスナーを追加し、ページが非表示または破棄されたときにリスナーを破棄します。
2. リスナーを追加した後、mapStateメソッドをシミュレートし、対応するデータをreduxでページのデータに挿入します。
3. reduxでデータの変更を監視するときは、ページデータを更新してページUIを更新する
4. mapDispatchメソッドをシミュレートして、ページがストアデータを変更するメソッドを提供します。

ページW.js:

const { store } = require('../redux/index');

const initPage = (params = {}, connect = []) => {
 定数{ 
  onLoad = ()=>{},
  onShow = ()=>{},
  非表示 = ()=>{},
  onUnload = ()=>{},
  データ = {}
  } = パラメータ;

 定数newPage = {
  ...パラメータ、
  //----------------
  OnLoad(...p) {
   onLoad.bind(this)(...p);
  },
  OnShow(...p) {
   onShow.bind(this)(...p);
  },
  OnHide(...p) {
   onHide.bind(this)(...p);
  },
  アンロード時(...p) {
   onUnload.bind(this)(...p);
  },
  //----------------
  // リスナーをクリアする clearStoreSubscribe() {
   (this.storeSubscribe)の場合{
    this.storeSubscribe();
    this.storeSubscribe = 未定義;
   }
  },
  // reduxでデータを取得する
  新しいデータを取得する() {
   定数 newItems = {};

   定数状態 = this.$store.getState();

   (接続) の場合
    Array.isArray(connect) の場合 {
     connect.forEach((キー) => {
      定数値 = 状態[キー];
      if (値 && this.data[キー] !== 値) {
       newItems[キー] = 値
      }
     })
    } そうでない場合 (typeof connect === 'function') {
     const リスト = connect(状態) || {};
     Object.keys(リスト).forEach((キー) => {
      const 値 = リスト[キー];
      if (値 && this.data[キー] !== 値) {
       newItems[キー] = 値
      }
     })
    }
   }

   新しいアイテムを返します。
  },
  // Reduxの変更をリッスンする handleReduxChange() {
   this.setData({
    ...this.getNewData()、
   });
  },
  //----------------
  データ: {
   ...データ
  },
  onLoad(...p) {
   const アプリ = getApp()
   this.$store = app.globalData.$store;
   this.setData({
    ...this.getNewData()、
   });

   this.OnLoad(...p);

   this._isOnLoad = true;
  },
  onShow (...p) {
   (!this.storeSubscribe)の場合{
    this.storeSubscribe = this.$store.subscribe(()=>this.handleReduxChange());
   }

   (!this._isOnLoad)の場合{
    this.setData({
     ...this.getNewData()、
    });
   }


   this.OnShow(...p);

   this._isOnLoad = false;
  },
  onHide(...p) {
   this.OnHide(...p);

   this.clearStoreSubscribe();
  },
  onUnload(...p) {
   this.OnUnload(...p);

   this.clearStoreSubscribe();
  },
  //----------------
  ディスパッチ(...p) {
   もし(this.$store){
    this.$store.dispatch(...p) を返します。
   }
  }
 }

 新しいページを返します。
}

const PageW = (params = {}, mapState = [], mapDispatch = ()=>{}) => {
 const ページ = initPage({...params}, mapState);
 ディスパッチリストをマップストアに格納します。

 page.mapDispatch = {
  ...ディスパッチリスト
 };

 Page(ページ)を返します。
}

モジュールをエクスポートします。

PageW の主な考慮事項と欠陥は次のとおりです。
1. WeChat アプレットの元のライフサイクル名を変更しないために、受信ページのライフサイクルを事前にハイジャックし、対応するライフサイクルが完了した後にバインドを使用して再度トリガーします。
2. redux はデータを更新するため、新しいデータ オブジェクトが生成されます。そのため、データの変更が検出されるたびに、新しいデータと古いデータが比較されます。setData が呼び出されるたびに、実際に変更されたデータのみが挿入されます。
3. ページ内のデータは、デフォルト ページによって作成されたデータを維持するだけでなく、redux connect 後のデータも追加します。ただし、現在、これら 2 つのデータの名前を安全に区別する方法がないため、ページのネイティブ データ内のデータ名は、connect によって挿入されたデータとは異なる必要があります。

テストページ:

2つのデータ項目testItemとtestItem2をインポートし、add2というメソッドをインポートしました。

PageW は '../../pageW/index' を必要とします。
const { ActionsFun } = require('../../redux/testItem/actions');

定数ページ = {
 データ: {
  4 : 4月
 },
 オンロード() {
  console.log('sub onLoad');
 },
 オンショー() {

 },
 トテスト() {
  コンソールにログ出力します。
  wx.navigateTo({
   URL: '/pages/test/index'
  })
 },
 ボタン1() {
  コンソールにログ出力します。
  this.mapDispatch.add2();
 },
 ボタン2() {
  定数 wwj は this.data です。
  this.setData({
   wwj: wwj + 2
  });
 },
}

const mapState = [ 'testItem', 'testItem2' ];

const mapDispatch = ({dispatch}) => {
 戻る {
  add2: (params) => ディスパッチ(ActionsFun.add(params))
 }
}

PageW(ページ、マップ状態、マップディスパッチ);

ネイティブ WeChat アプレットの開発における redux の詳細な使用に関するこの記事はこれで終わりです。アプレットでの redux の使用に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。皆様が今後も 123WORDPRESS.COM を応援してくれることを願っています。

以下もご興味があるかもしれません:
  • ミニプログラムに redux/immutable/thunk サードパーティライブラリを統合する方法
  • WeChatアプレットReduxバインディング例の詳細な説明

<<:  Ubuntu 16.04 にソースコードから Mininet をインストールする

>>:  WindowsでMysql5.7.17のインストールと起動に失敗する問題を解決する

ブログ    

推薦する

条件によるMysqlカウントの複数の実装方法を詳細に解説

最近、あるウェブサイトのバックエンドに一連の統計機能を追加していたのですが、条件によるカウントが必要...

Nodejs での WeChat アプレット メッセージ プッシュの実装

サブスクリプションメッセージテンプレートを選択または作成するWeChat アプレットにログインし、「...

React+axios は github 検索ユーザー機能を実装します (サンプル コード)

負荷リクエスト成功リクエストに失敗しました cmdをクリックし、ファイルパスでEnterキーを押しま...

MySQL ストアド プロシージャの作成と呼び出しの詳細な説明

目次序文ストアドプロシージャ: 1. ストアドプロシージャの作成と呼び出し1. ストアドプロシージャ...

MySql マスタースレーブレプリケーションの実装原理と構成

データベースの読み取りと書き込みの分離は、トラフィック量の多い大規模システムやインターネット アプリ...

Webpackプラグインを書いてnpmに公開するための80行のコード

1. はじめに最近、 Webpackの原理を勉強しています。これまでは Webpack の設定方法し...

W3Cチュートリアル(1):W3Cを理解する

1994 年に設立された組織である W3C は、共通プロトコルの開発を促進し、それらの相互運用性を確...

UDP 接続オブジェクトの原理分析と使用例

以前、UDP を使い始めるために簡単な UDP サーバーとクライアントの例を作成しましたが、実際に使...

Centos7 サーバーで jar パッケージ プロジェクトを開始する最良の方法

序文Linux 上で jar パッケージを実行する方法は誰もが知っています。なぜ別々に話したいのでし...

MySQLの水平および垂直テーブルパーティションの説明

前回の記事で、MySQL ステートメントの最適化には限界があると述べました。MySQL ステートメン...

MySQL ストアド プロシージャのエラー処理例の詳細な説明

この記事では、例を使用して MySQL ストアド プロシージャのエラー処理について説明します。ご参考...

Linux システムで Tomcat のポート 80 を使用する方法

アプリケーションシナリオ多くの場合、Linux サーバーに tomcat や nginx などのソフ...

Nginx リバース プロキシから go-fastdfs へのケースの説明

背景go-fastdfs は、http プロトコルをサポートする分散ファイルシステムです。一般的なプ...

SQL 実装 LeetCode (185. 部門内で最も給与の高い上位 3 名)

[LeetCode] 185. 部門別給与上位3位従業員テーブルにはすべての従業員が保持されます。...

Nginx 最適化サービスで Web ページ圧縮を実装する方法

リソースを節約するためにWebページの圧縮を設定する1.まず、設定を変更しましょう vim /usr...