原生微信小プログラム開発中の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で行われる。
結合データエンティティ:
こことreactでは使い方が違います。WeChatアプレットには対応のコントロールがありませんので、直接にap.jsのglobalDataでメンテナンスします。このように各ページでstoreを直接取得できます。
app.js:
reactでは,connect法は高次のコンポーネントによって実現されるが,この方法はWeChatウィジェットを適用しない。reduxはsubscribe方法を提供してstoreにおけるデータの変化を監督しています。だから、最初の設計:
1、ページを計上または表示するたびに、傍受を追加し、ページを隠しまたは廃棄する時に傍受を廃棄する
2、モニターを追加したら、mapState方法をシミュレーションし、対応reduxのデータをページのdataに注入する。
3、Reduxでデータの変化を聞いたときに、画面dataを更新し、ページUIの更新を実現する。
4、mapDisplatch方法をシミュレートし、ページにstoreデータを修正する方法を提供する。
pageW.js:
1、微信小プログラムの元のライフサイクルを維持するために、事前にページに入ってきたライフサイクルを乗っ取ってから、Bindでライフサイクルに対応して再起動します。
2、データを更新すると新しいデータオブジェクトが生成されますので、データが変化するたびに、新しいデータと古いデータをモニターして比較します。setsData毎に、確実に変化するデータだけを入れます。
3、ページのdataは、デフォルトページで作成したdataデータを維持し、またredux connect後のデータを加入していますが、現在はこの2つのデータの名前を安全に区分していませんので、ページの原生dataのデータ名はconnectに注入されたデータとは違います。
テストページ:
testItem,testItem 2のデータを導入し、add 2の方法を導入しました。
複雑なシーンの中には多くのデータが複数の異なるページの間を行ったり来たりします。しかし、プログラムページの直接データ通信方式は非常に簡単です。通常は自分で全体の対象を維持して共有データを保存する必要があります。しかし、単純に共有データエンティティを維持すると、業務ロジックの複雑化によって、膨大になりすぎて、データの修正がうまく追跡できなくなります。加えて、共通データエンティティにおけるデータの修正とページの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の使用内容は私達の以前の文章を検索したり、下記の関連文章を引き続き閲覧したりしてください。これからもよろしくお願いします。