dva

repository·master·Indexed 12 days ago

https://github.com/dvajs/dva

A lightweight front-end framework that simplifies state management by combining Redux, Redux-Saga, and React-Router into a cohesive, Elm-inspired model pattern. It provides a low API surface for managing state, logic, and side effects through models consisting of namespaces, state, reducers, effects, and subscriptions.

Tokens
26.3K
Snippets
97
Records
129
Agent score
94%

What's inside dva

  1. Overview of dva features

    master

    dva is a lightweight state management library inspired by Elm. It is designed to be easy to learn and use, especially for Redux users. Key features include:

    • Minimal API Surface: It provides only 6 core APIs. When used with umi, the required API usage can be reduced to zero.
    • Elm-inspired Architecture: It organizes the model using reducers, effects, and subscriptions, which simplifies the concepts typically introduced by Redux and Redux-Saga.
    • Plugin Mechanism: Supports plugins like dva-loading to automate common tasks, such as handling loading states without manually calling showLoading and hideLoading everywhere.
  2. Overview of dva

    master

    dva is a lightweight frontend framework inspired by elm and choo. It is built upon redux, redux-saga, and react-router.

    Key Features

    • Ease of Use: Features only 6 core APIs. It is particularly friendly to Redux users and can be used with umi to reduce API usage to near zero.
    • Elm-inspired Model: Organizes the application model using reducers, effects, and subscriptions.
    • Plugin Mechanism: Supports plugins like dva-loading to automatically handle loading states, eliminating the need for manual showLoading and hideLoading calls.
    • HMR Support: Supports Hot Module Replacement (HMR) for components, routes, and models via babel-plugin-dva-hmr.
  3. Key features of dva

    master

    dva provides several core features to streamline application development:

    • Low API Surface: It features only 6 core APIs, making it very friendly for Redux users. When used with umi, the required API surface is reduced to zero.
    • Elm-inspired Model Organization: Models are organized using reducers, effects, and subscriptions.
    • Plugin Mechanism: Supports plugins like dva-loading to automatically handle loading states, removing the need to manually call showLoading and hideLoading.
    • Hot Module Replacement (HMR): Supports HMR for components, routes, and models via babel-plugin-dva-hmr.
  4. How to organize models in dva

    master

    dva uses Elm-inspired concepts to organize application logic into models. Instead of separating Redux reducers, Sagas, and React Router logic into disparate files, you group them into a single model structure using three main pillars:

    1. Reducers: Handle synchronous state updates.
    2. Effects: Handle asynchronous side effects (powered by redux-saga).
    3. Subscriptions: Listen to state changes or actions to trigger side effects.

    This approach simplifies the mental model for managing complex application states.

  5. Organize components into Route and Presentational types

    master

    dva encourages a specific component architecture:

    • Route Components: Located in the /routes/ directory. These are container components that are connected to models and manage page-level logic.
    • Presentational Components: Located in the /components/ directory. These are UI components that focus on how things look and are generally not connected to models directly.
  6. Understand the dva Data Flow

    master
    dva follows a unidirectional data flow pattern. Data flows from actions/effects through reducers to update the state, which then triggers re-renders in the UI. This cycle ensures predictable state management by centralizing all state changes.
  7. Essential JavaScript for dva.js

    master

    To use dva, you should be familiar with several ES6+ features. This includes:

    • Variable Declarations: Use const for constants and let for variables to ensure block-scoping. Avoid var.
    • Template Strings: Use backticks (`) for string interpolation and multi-line strings.
    • Default Parameters: Define default values in function signatures.
    • Arrow Functions: A concise syntax for functions that also inherits the lexical this context.
    • Modules: Use import to bring in modules (full or partial) and export (default or named) to share them.
    • Destructuring Assignment: Extract properties from Objects or elements from Arrays directly into variables.
    • Spread Operator (...): Use it to assemble arrays, collect function arguments, or merge objects.
    • Promises: Handle asynchronous operations using .then() and .catch().
    • Generators: Used extensively in dva effects to manage asynchronous logic using yield.
    // Example of Generator used in a dva effect
    app.model({
      namespace: 'todos',
      effects: {
        *addRemote({ payload: todo }, { put, call }) {
          yield call(addTodo, todo);
          yield put({ type: 'add', payload: todo });
        },
      },
    });
  8. Use Subscriptions to listen to data sources

    master

    Subscriptions allow you to listen to external data sources (like time, WebSockets, keyboard input, or route changes) and dispatch actions accordingly. The subscription format is ({ dispatch, history }) => unsubscribe.

    Example: Triggering a fetch action when the user navigates to the /users path using the history object.

    app.model({
      subscriptions: {
        setup({ dispatch, history }) {
          history.listen(({ pathname }) => {
            if (pathname === '/users') {
              dispatch({
                type: 'users/fetch',
              });
            }
          });
        },
      },
    });
  9. Understand Models, State, and Actions

    master

    A Model is the core unit of data management in dva. It consists of:

    • State: The data representing the model's current status. It should be treated as immutable data (always return a new object instead of mutating the existing one) to ensure independence, testability, and support for features like time travel.
    • Action: A plain JavaScript object that describes a behavior. It must have a type property. Actions are the only way to trigger changes in the State.

    While you can access the top-level state via the app._store property, it is generally not recommended for standard application logic.

    const app = dva();
    console.log(app._store); // Accessing top-level state