These days, Redux status management frameworks are everywhere. A few days ago, I found Rematch, Mirror, Smox and Xredux on the Internet. I used them all and found that they are all porcelain dolls.

  • DvaJS Github Stars 12000 +
  • Rematch Github Stars 5000 +
  • Mirror Github Stars 1200 +

It goes something like this:

model({
    state:... .reducers: {
        aaa(playload)
        bbb(playload)
    },
    effects: {
        ccc(playload)
        ddd(playload)
    }
})
Copy the code

Aesthetic fatigue? H, let’s recommend a react-coat:

Project address: github.com/wooline/rea…

class ModuleHandlers extends BaseModuleHandlers { @reducer public aaa(playload): State {... } @reducer private bbb(playload): State {... } @effect("ajaxLoading")
  public asyncccc(playload) {... } @effect("loginLoading")
  private async ddd(playload) {...}
}
Copy the code

Spring style? Ng style?

You might say, use Class, no, I like FP style. I would say that this is a state management framework, not a React UI framework. Don’t be FP for FP’s sake, just like when JS was object-oriented programming and process oriented was a monster.

Armed to teeth TS type reflexes

React-coat embraces Typescript directly:

Type reflection on action calls:

Type reflection when dynamically loading modules:

Type reflection of the Store State structure:

Even route parameters have type reflection:

Support single page SPA and server rendering SSR isomorphism

  • And SSR can also be enjoyed during development: “hot update”
  • Also supports SPA(single page) + SSR(server rendering) one-click switch.

Open the project root./package.json, in the “devServer” TAB, set SSR to true to enable server rendering, and set it to false to use browser only rendering

Please move on to another article about server rendering SSR: juejin.cn/post/684490…

Powerful and convenient Dispatch actions

Compare the syntax of the Dispatch Action from each framework:

/ / the Dva
yield put({type: 'moduleA/increment'.payload: 2});

/ / in the Rematch
dispatch.moduleA.increment(2);

/ / in the Mirror
actions.moduleA.increment(2);

/ / the React - coat
import moduleA from "modules/moduleA/facade"; . awaitthis.dispatch(moduleA.actions.increment(2));
Copy the code
  • In terms of syntax simplicity, Dva uses the yield put of saga, and also writes type and payload, which is the most tedious. The other three use method calls directly, which are simpler.

  • Rematch and Mirror put all actions into a global variable, while react-Coat is decentralized and introduces moduleA as needed, which helps keep the system loose.

  • Semantically React – coat still show keep dispatch keyword, moduleA. Actions. The increment (2) the return is still is the Action, Dispatch (Action) remains intact as Redux’s basic philosophy, and Rematch and Mirror have become traditional MVC’s.

  • Functionally, only Dva and React support synchronization effects. Neither of the other two styles is supported, or did I not notice? What is synchronization effect? Such as:

    • Query triggers an effect and updateState triggers a reducer
    • UpdateState needs to wait for query execution to complete before dispatch
    // Dva uses Saga's put. Resolve to support synchronization effect
    yield put.resolve({type: 'query'.payload:1});
    yield put({type: 'updateState'.payload: 2});
    Copy the code
    // React-coat allows awiat dispatch directly
    await this.dispatch(thisModule.actions.query(1));
    this.dispatch(thisModule.actions.updateState(2));
    Copy the code
  • React-coat’s unique features include type reflection and smart hints for action names and parameters, and control of public private permissions to give you a feel for real encapsulation. Imagine if multiple people were developing multiple modules in parallel. Would you need to write a large API for your modules?

Thorough modularization

Since it is an enterprise application, the modular nature is indispensable, including module encapsulation, code segmentation, loading on demand. The main purpose of modularization is to break up complex systems, decouple and reuse.

In the above framework, the modularity of Rematch and Mirror is weak and not elegant, so skip it. Both Dva and React-Coat have powerful modularity, where Dva can be configured automatically with UMI.

Dynamic loading of model and Component in DVA depends on routing configuration:

{
  path: '/user'.models: (a)= > [import(/* webpackChunkName: 'userModel' */'./pages/users/model.js')].component: (a)= > import(/* webpackChunkName: 'userPage' */'./pages/users/page.js'),}Copy the code

React-coat code segmentation and routing hierarchy:

  • Code splitting only does code splitting and does not involve routing, because modules are not necessarily loaded in a non-routing manner.
  • Routing only does routing, not code splitting, because modules don’t have to do code splitting.
  • A Module is packaged into a bundle, including Model and views, to avoid fragmentation.
// Define code splitting
export const moduleGetter = {
  app: (a)= > {
    return import(/* webpackChunkName: "app" */ "modules/app");
  },
  photos: (a)= > {
    return import(/* webpackChunkName: "photos" */ "modules/photos"); }},Copy the code

React- Coat supports dynamic loading of routes and non-routes

// Use route load:
const PhotosView = loadView(moduleGetter, ModuleNames.photos, "Main"); . <Route exact={false} path="/photos" component={PhotosView} />
Copy the code
// Direct load:
const PhotosView = loadView(moduleGetter, ModuleNames.photos, "Main"); . render() {const {showDetails} = this.props;
  return showDetails ? <DetailsView /> : <ListView />;
}
Copy the code
  • Dva modules are divided into Page UI mainline. React-coat divides modules by high cohesion and low coupling of business functions. The latter is better suited for decoupling and reuse.
  • Dva uses centralized configuration to centralize Page, route, model, and code segmentation in a central file. React-coat is decentralized, encapsulating their logic in their own modules. Model, code segmentation, and routing are governed by layers without interference from each other. The latter is cleaner and tidy.
  • Dva makes a code split package for each model and Component; React-coat makes a Module into a code split package. The former is too fragmented, while the latter is more consistent with the concept of bundles.
  • React-coat supports dynamic routing and non-routing View loading, and takes longer steps on two legs.
  • When react-coat dynamically loads a View, it automatically imports the Model, and does not need to manually load the Model. This is true route componentization.

For more differences, see: Talk to DvaJS storm, is DvaJS challenger? Or another wheel?

Calls and collaboration across modules

In complex and long business processes, cross-module invocation and collaboration are indispensable. Dva, Rematch, Mirror and React-Coat all support cross-module action distribution and cross-module State reading. Such as:

/ / in the Mirror
if(resphonse.success){
    actions.moduleA.doSomeEffect();
    actions.moduleB.doSomeEffect();
}
Copy the code

This is a concatenated invocation pattern, suitable for some tightly coupled business flows. But for some loosely coupled business processes, the best approach is the observer mode, or event broadcast mode.

Scenario: When moduleA executes an action, moduleB, moduleC, moduleD… Each needs to perform some individual action

This is react-Coat’s unique killer: the ActionHandler concept.

class ModuleB {
    // Listen for the "ModuleA/update" action in ModuleB
    async ["ModuleA/update"] () {await this.dispatch(this.action.featchData())
    }
}

class ModuleC {
    // Listen for the "ModuleA/update" action in ModuleC
    async ["ModuleA/update"] () {await this.dispatch(this.action.featchData())
    }
}
Copy the code

React-coat active call and event broadcast are supported. Both modes should be used to catch and hard. I just want to know if you’re hot or not? 😂