1. Why?

Why do you study DVA?

Umijs has also been used for a long time, some of his plug-ins (Qiankun, ANTD... And so on have been used a lot, but have not touched the global state management of DVA. Why is that? 1. The global state is seldom used in the project. It is basically the background ID that transmits information to each other. I wrote a small state management system based on the context (createContext,useReducer) and it worked fine. I even wrote a set of I18n based on it. But each component needs to introduce context functions, which can be a little trickyCopy the code

Why dVA?

1. The next project is ready to use more mature global state management, and DVA is more suitable for technical difficulty. Umi 3. I still have an understanding of vuEX and have used it before. This learning is a process of knowledge accumulationCopy the code

2. Introduction of dva

dvajs

If dVA is used in UMI, you can download the plug-in and configure it. I wait for the dog Gospel.

3. Understanding of DVA model (for me)


1. global

Dva’s global model, which includes the Dispatch trigger function, attributes of the current route, etc., is considered a global object (root).

{
  children: {$$typeof: Symbol(react.element), key: null.ref: null.props: {... },type: ƒ,... },dispatch: ƒ (action),
  history: {length: 21.action: "POP".location: {... },createHref: ƒ.push: ƒ,... },location: {pathname: "/".search: "".hash: "".query: {... },state: undefined},
  match: {path: "/".url: "/".isExact: true.params: {... }},route: {path: "/".component: {... },exact: true},
  routes: (2) ({...}, {...}),staticContext: undefined
}
Copy the code
2. model

A local state operation model for DVA disassembly. It contains five main attributes: namespace, the state, reducer, the effects of subscriptions. Models are relatively independent of each other, but can also operate with each other.

3. namespace

As the name implies, the namespace, which determines the module in which the model resides. Once compiled by DVA, it will be mounted into global. like

{...route: {path: "/".component: {... },exact: true},
  routes: (2) ({...}, {...}),staticContext: undefined.user: {name:"sanfeng"}}Copy the code

[root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] This facilitates subsequent triggering operations

4. state

State. It’s basically an object value, but it looks like it could be any type of value. The value is mounted to global with a namespace key.

5.action

Action is a plain javascript object that is the only way to change State. Action must have the type attribute to specify the specific behavior. Other fields can be customized. Such as

dispatch({ type: "user/change".name: "ruansanfeng" });
Copy the code

Type specifies that the function to be triggered is a Model with a namespace of User and that the actions in Reducer or Effects are executed. Note: In the same model, keys of Reducer or Effects cannot have the same name. The remaining key-values indicate the parameter values passed. So we traditionally use the payload key to pass all parameters.

6.reducers

Synchronize change status. As anyone familiar with VUEX knows, state changes are synchronous and asynchronous. Reducers is an object and values is a function. There are two input parameters: state represents the current state, and action represents the input parameter value.

  reducers: {
    / / write one
    save: (state, action) = >({... state, ... action.payload, }),/ / write two
    delete(state,action){
    return{
      ...state,
      list:state.list.filter(it= >it.id! =action.payload.deleteId) } } },Copy the code

You can write it either way.

7.effects

Asynchronously changing state. The general background data request is written in this method. Effects is also an object, so overall writing can be similar to reducers. The async and await syntax is more intuitive than the Generator syntax, and the state cannot be changed. The input parameters of the function have also been changed. The first input parameter is action, which is the value of the input parameter we pass. The second entry is a set of operations, the most important of which are Call and PUT.

 effects: {
    *query({ payload }, { call, put }) {
      const data = yield Promis();
      yield put({type:'save',payload:data})
    },
  },
Copy the code

Less frequently, call means to execute an asynchronous function. A PUT emits an action, similar to a dispatch. The difference is that the action triggering this model does not need to add namespace and oblique bar, as in the previous example of save.

8.subscriptions

The Subscription semantics are subscriptions that are used to subscribe to a data source and then dispatch required actions based on conditions. The data sources can be the current time, the server’s Websocket connection, keyboard input, geolocation changes, history route changes, and so on. Subscriptions here are actually quite complicated, and more cases need to be handled by third-party libraries. See here for details

4. Bind to the UI

import { IndexModelState, connect } from "umi";

export default connect(({ user }: { user: IndexModelState }) = > ({
  user,
}))(({ user, dispatch }) = > {
  ///react ui
});
Copy the code

The state types everywhere in the model can be introduced by UMI, a strong batch. The first is an anonymous callback function, which returns the namespace of the model required by the current module. The second component, the React component, takes the global parameter and uses the structure to retrieve the desired state. Colleagues can get dispatches to trigger actions.

That’s all for now, thank you.


Author information: Shuan Zhang, Renhe Future front-end engineer.