原生微信小プログラム開発中のreduxの使用詳細


前提
複雑なシーンの中には多くのデータが複数の異なるページの間を行ったり来たりします。しかし、プログラムページの直接データ通信方式は非常に簡単です。通常は自分で全体の対象を維持して共有データを保存する必要があります。しかし、単純に共有データエンティティを維持すると、業務ロジックの複雑化によって、膨大になりすぎて、データの修正がうまく追跡できなくなります。加えて、共通データエンティティにおけるデータの修正とページのUIとの間には、あまり良い同期手段がないため、ページと対応するデータエンティティの間で同じデータを維持する必要があり、動作が非常に不便である。
前にTaroを使ってreact+reduxの構造で微信小プログラムを開発しましたが、redux全体で上記の問題を解決できます。だがタロー自身も、受け入れられない潜在的な問題を抱えていた。原生では第三者の二次パッケージを使用しないという原則に基づいています。ずっと試してみたいのですが、原生微信小プログラムの開発でreduxにアクセスします。
解決すべき問題
1、reduxライブラリのアクセス
2、ページUIとreduxデータの結合
reduxライブラリの導入
1、reduxのインストールはnpmとyarnを使ってもいいです。
具体的にはredux中国語の公式サイトは以下の通りです。https://www.reduxjs.cn/introduction/getting-started/
2、WeChatウィジェットを外部のnpmパッケージに導入する。
WeChatウィジェットIDEAを使用して、toolsのBuild npmで、miniprogram_を生成します。npm

3、reduxライブラリReferenceErrer:process is not definedエラーの解決。

WeChatアプレットBuiild npmツールのため、構築時にnodeprocess環境変数を導入しないが、reduxは異なるenvに対応する最適化を行った。そのため、構築されたパケットはprocess変数を失ってしまいます。一番便利な解決方法は、完成したカバンの中に自分で必要なプロcessを注入することです。

このようにして、基本的にすべての第三者ライブラリで発生したプロcessパラメータの欠落の問題を解決することができます。Build npmツールを実行するたびに手動で修正する必要があります。複数の第三者ライブラリが手動で修正する必要があるなら、大変です。シナリオを通して、astツリーなどのツールを使って、完全に動的に修正して、人件費を節約する必要があります。
以上より、reduxの導入が完了しました。
プロジェクトにreduxを追加する
1、storeの作成
commbineReducersを使って異なるエンティティを統合し、createStoreを使ってstoreエンティティを作成し、エクスポートします。データの統一性のために、reduxは原則として一つのプロジェクトは一つのstoreだけ初期化されるので、後続のどの操作も現在生成されたstoreで行われる。
結合データエンティティ:

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

const reducer = combineReducers({
 testItem: testItem.testItem,
 testItem2,
 user
});

module.exports = {
 reducer
}

エクスポートのstore:

const { createStore, applyMiddleware } = require('redux');
const { reducer } = require('./reducers');
const { logger } = require('redux-logger');

const store = createStore(
 reducer,
 applyMiddleware(logger)
)

module.exports = {
 store
}

2、グローバル保守store
こことreactでは使い方が違います。WeChatアプレットには対応のコントロールがありませんので、直接にap.jsのglobalDataでメンテナンスします。このように各ページでstoreを直接取得できます。
app.js:

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

//app.js
App({
 globalData: {
  $store: store,
  getState: ()=> store.getState(),
 }
})

シミュレーション
reactでは,connect法は高次のコンポーネントによって実現されるが,この方法はWeChatウィジェットを適用しない。reduxはsubscribe方法を提供してstoreにおけるデータの変化を監督しています。だから、最初の設計:
1、ページを計上または表示するたびに、傍受を追加し、ページを隠しまたは廃棄する時に傍受を廃棄する
2、モニターを追加したら、mapState方法をシミュレーションし、対応reduxのデータをページのdataに注入する。
3、Reduxでデータの変化を聞いたときに、画面dataを更新し、ページUIの更新を実現する。
4、mapDisplatch方法をシミュレートし、ページにstoreデータを修正する方法を提供する。
pageW.js:

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

const initPage = (params = {}, connect = []) => {
 const { 
  onLoad = ()=>{},
  onShow = ()=>{},
  onHide = ()=>{},
  onUnload = ()=>{},
  data = {}
  } = params;

 const newPage = {
  ...params,
  // ----------------
  OnLoad(...p) {
   onLoad.bind(this)(...p);
  },
  OnShow(...p) {
   onShow.bind(this)(...p);
  },
  OnHide(...p) {
   onHide.bind(this)(...p);
  },
  OnUnload(...p) {
   onUnload.bind(this)(...p);
  },
  // ----------------
  //     
  clearStoreSubscribe() {
   if (this.storeSubscribe) {
    this.storeSubscribe();
    this.storeSubscribe = undefined;
   }
  },
  //   redux   data
  getNewData() {
   const newItems = {};

   const state = this.$store.getState();

   if (connect) {
    if ( Array.isArray(connect) ) {
     connect.forEach((key) => {
      const value = state[key];
      if (value && this.data[key] !== value) {
       newItems[key] = value
      }
     })
    } else if (typeof connect === 'function') {
     const list = connect(state) || {};
     Object.keys(list).forEach((key) => {
      const value = list[key];
      if (value && this.data[key] !== value) {
       newItems[key] = value
      }
     })
    }
   }

   return newItems;
  },
  //    redux   
  handleReduxChange() {
   this.setData({
    ...this.getNewData(),
   });
  },
  // ----------------
  data: {
   ...data
  },
  onLoad(...p) {
   const app = getApp()
   this.$store = app.globalData.$store;
   this.setData({
    ...this.getNewData(),
   });

   this.OnLoad(...p);

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

   if (!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();
  },
  // ----------------
  dispatch(...p) {
   if (this.$store) {
    return this.$store.dispatch(...p);
   }
  }
 }

 return newPage;
}

const PageW = (params = {}, mapState = [], mapDispatch = ()=>{}) => {
 const page = initPage({...params}, mapState);
 const dispatchList = mapDispatch(store) || {};

 page.mapDispatch = {
  ...dispatchList
 };

 return Page(page);
}

module.exports = PageW;

PageWでは主に以下の問題を考慮し、不足しています。
1、微信小プログラムの元のライフサイクルを維持するために、事前にページに入ってきたライフサイクルを乗っ取ってから、Bindでライフサイクルに対応して再起動します。
2、データを更新すると新しいデータオブジェクトが生成されますので、データが変化するたびに、新しいデータと古いデータをモニターして比較します。setsData毎に、確実に変化するデータだけを入れます。
3、ページのdataは、デフォルトページで作成したdataデータを維持し、またredux connect後のデータを加入していますが、現在はこの2つのデータの名前を安全に区分していませんので、ページの原生dataのデータ名はconnectに注入されたデータとは違います。
テストページ:
testItem,testItem 2のデータを導入し、add 2の方法を導入しました。

const PageW = require('../../pageW/index');
const { ActionsFun } = require('../../redux/testItem/actions');

const page = {
 data: {
  wwj: 4
 },
 onLoad() {
  console.log('sub onLoad');
 },
 onShow() {

 },
 toTest() {
  console.log('toTest');
  wx.navigateTo({
   url: '/pages/test/index'
  })
 },
 button1() {
  console.log('button1');
  this.mapDispatch.add2();
 },
 button2() {
  const { wwj } = this.data;
  this.setData({
   wwj: wwj + 2
  });
 },
}

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

const mapDispatch = ({dispatch}) => {
 return {
  add2: (params) => dispatch(ActionsFun.add(params))
 }
}

PageW(page, mapState, mapDispatch);

ここで、原生微信小プログラムの開発におけるreduxの使用についての詳細な文章をここに紹介します。より多くの関連小プログラムreduxの使用内容は私達の以前の文章を検索したり、下記の関連文章を引き続き閲覧したりしてください。これからもよろしくお願いします。