This is the 14th day of my participation in the August Text Challenge.More challenges in August
The introduction of Rematch
Rematch
There is no templateRedux
Best practices can be understood asRedux
Is a substitute for.Rematch
Depends on theRedux
And solved some problemsRedux
Is a pain point.- At the level of use, and
Dva
Compared to theRematch
将Redux-saga
replacedpromise/async await
.
Use of Rematch on the Web platform
First, Rematch itself is platform independent of browsers, Nodes, applets, etc. Rematch can be used as long as you can run JS. Also, Rematch needs to work with Redux, which is platform-independent. Finally, when used with React, you need to use React-Redux, which is tied to the Web platform.
Rematch in MiniApp
To run on applets, the first thing you should do is deprecate react-redux. We need a similar set of Connect in React-Redux. State and Dispatch need to be passed into the page, and the dispatch operation of the page can trigger the update of the applet page.
Bring benefits and problems
- income
The first step is to use what the Redux community already has, because Rematch also supports Redux’s middleware and other features. In addition, the redux-like development experience of mapState and mapDispatch, as well as the mode of multi-model and mixed state, Reducer and effects, will greatly facilitate the development of pages. Meanwhile, as the whole is similar to Redux template, The cost of understanding and maintaining other people is relatively low.
- issues
The main reason is the cost of getting started with Rematch. Only by being familiar with the use of Rematch in React, can you better transition to Rematch in MiniApp.
Expected use of Rematch in MiniApp
// page/index/index.js
import connect from 'path/to/rematch-in-miniapp/connect'
const mapState = (state) = > ({})
const mapDispatch = (dispatch) = > ({})
const pageConfig = {
anyMethod() {
this.dispatch.dialog.showCommonPopup()
}
}
Page(
connect(
pageConfig
)(mapState, mapDispatch)
)
// pages/index/index.wxml
<view>{{/* data in rematch */}}</view>
Copy the code
The core code
module.exports = (pageConfig) = > (mapState, mapDispatch) = > {
const store = createStore()
const fromMapState = () = > mapState(store.getState())
const fromMapDispatch = mapDispatch(store.dispatch)
returnenhancedPageConfig(pageConfig, { ... store, fromMapState, fromMapDispatch, }) }Copy the code
This accepts the pageConfig, mapState, and mapDispatch parameters, and returns enhancedPageConfig.
function enhancedPageConfig(pageConfig, store) {
const {
fromMapState,
fromMapDispatch,
} = store
const originalOnLoad = pageConfig.onLoad || noop
const injectDispatchApi = (context) = > context.dispatch = fromMapDispatch
const addSyncStoreStateListener = (context) = > store.subscribe(() = > {
syncStoreState(context, fromMapState())
})
return {
...pageConfig,
onLoad: function (. args) {
injectDispatchApi(this)
syncStoreState(this, fromMapState())
addSyncStoreStateListener(this)
return originalOnLoad.apply(this, args)
}
}
}
Copy the code
In the implementation of enhancedPageConfig,
First hijack the onLoad method and inject the Dispatch into this.
Then add syncStoreStateListener, which monitors store changes in rematch through store.subscribe, and then execute syncStoreState when the changes are triggered.
For an implementation of syncStoreState:
const debounce = require('./debounce')
const syncStoreState = debounce((context, storeState) = > {
const readyToSet = {}
const {
data: originalData,
setData
} = context
for (let key in storeState) {
const shouldUpdate = Boolean(originalData[key] ! == storeState[key])if(! shouldUpdate)continue
readyToSet[key] = storeState[key]
}
const shouldSetData = Boolean(Object.keys(readyToSet).length)
if(! shouldSetData)return
console.log(` trigger setData `, readyToSet)
setData.call(context, readyToSet)
}, 300)
module.exports = syncStoreState
Copy the code
Since each reducer or effects triggered by a store triggers store.subscribe, store data does not change in events that may be triggered several times.
Therefore, diff the latest store state and the original data first, and data update needs to be triggered only when they are different.
Another way to dynamically add variables from rematch is by iterating over the rematch data to be added and executing this.setData({}) one by one.
Finally, the outermost layer is guaranteed by debounce not to trigger too many times over a period of time.
conclusion
At this point, you can run Rematch on the applets platform.