This is the 14th day of my participation in the August Text Challenge.More challenges in August

The introduction of Rematch

  • RematchThere is no templateReduxBest practices can be understood asReduxIs a substitute for.
  • RematchDepends on theReduxAnd solved some problemsReduxIs a pain point.
  • At the level of use, and DvaCompared to theRematchRedux-sagareplacedpromise/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.