ネイティブ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のインストールと起動に失敗する問題を解決する

推薦する

Linuxドライバのプラットフォームバスの詳細説明

目次1. プラットフォームバスの紹介1.1. Linuxドライバの分離と階層化1.1.1. Linu...

Vue ページでよりエレガントに画像を紹介する方法

目次エラーのデモンストレーション計算により画像が変わらない場合は直接インポートするCSS変数による画...

Dockerで同じIDを持つ2つのイメージを削除する

今日 Docker コンテナを作成したとき、誤ってイメージの名前を間違って入力しました。その結果、コ...

jsonファイルの書き方の詳細説明

目次JSONとはなぜこの技術なのでしょうか? JSONの使い方- データ形式- メモ- JSには2つ...

LinuxでTomcatのポート番号を変更する方法

ここには複数の Tomcat があります。それらを同時に使用する場合は、ポート番号を別の番号に変更す...

MySQLテーブル名の大文字と小文字を区別しない設定方法の詳細な説明

デフォルトでは、Linux の MySQL はテーブル名の大文字と小文字を区別します。 MySQL ...

Vue カスタム箇条書きボックス効果 (確認ボックス、プロンプトボックス)

この記事の例では、参考のためにVueカスタムポップアップ効果の具体的なコードを共有しています。具体的...

最もよく使用されるJavaScriptイベントについて詳しく学ぶ

目次JavaScript イベント:よく使用されるイベント:イベントアクション要約するJavaScr...

VMware 仮想マシンで HTTP サービスを確立して分析する手順

1. xshell を使用して仮想マシンに接続するか、仮想マシンに直接コマンドを入力します。以下はx...

MySQL 10進数符号なし更新負数を0に変換

今日、インターフェースの同時実行の問題を検証したところ、これまでredisで解決していた同時実行のプ...

jQueryアニメーションを理解するのに役立つ記事

目次1. 要素の表示と非表示を制御する show() hide() 2. 要素の透明度を制御する f...

JS でオブジェクト プロパティを簡単にトラバースするいくつかの方法

目次1. 自己列挙可能なプロパティ2. Object.values()はプロパティ値を返します3. ...

background-positionプロパティでのパーセンテージ値の使用法の検討

背景位置が背景画像の表示に与える影響この2日間のプロジェクトでホームページの写真を入れ替えていたとこ...

MySQL インデックスがソートに与える影響の分析例

この記事では、例を使用して、MySQL インデックスがソートに与える影響を説明します。ご参考までに、...

HTML での位置の使用に関する簡単な紹介

昨日 HTML を少し学んだばかりで、JD.com の検索バーを作るのが待ちきれませんでした。 作っ...