Frontend Development 17 min read

Understanding Dva: A Lightweight Frontend Framework Based on Redux and Redux‑Saga

This article explains what Dva is, the problems it solves, its advantages and disadvantages, core concepts, minimal application structure with code examples, and the underlying implementation details, comparing it with React, React‑Redux, and Redux‑Saga, helping developers understand its role in frontend development.

ByteFE
ByteFE
ByteFE
Understanding Dva: A Lightweight Frontend Framework Based on Redux and Redux‑Saga

Dva is a lightweight application framework built on top of Redux and redux‑saga, additionally bundling react‑router and fetch to simplify development experience.

Problems Dva Solves

Traditional Redux projects suffer from file switching overhead, difficulty organizing business models, cumbersome saga creation, and complex entry setup involving store creation, middleware configuration, router initialization, Provider binding, saga initialization, and HMR handling.

Advantages of Dva

Easy to learn and use with only six APIs, especially friendly to Redux users; when used with Umi, it can be reduced to zero APIs.

Elm‑inspired model concept using reducers, effects, and subscriptions to organize state.

Plugin mechanism (e.g., dva-loading ) automatically handles loading states.

Supports HMR via babel-plugin-dva-hmr .

Disadvantages of Dva

Future uncertainty: after the Dva@3 plan was announced, the official team has largely stopped maintenance.

For many simple scenarios, Hooks can replace Dva.

Applicable Scenarios

Business scenarios with complex component communication requiring state management.

Technical scenarios using React class components.

Core Concepts

Dva follows the Redux data flow: actions are dispatched, synchronous actions go directly to reducers to update state, while asynchronous actions trigger effects (sagas) before reaching reducers.

Key Redux concepts include State (immutable JavaScript object), Action (plain object), dispatch (function to trigger actions), Reducer (pure function to compute new state), Effects (side‑effects handled by redux‑saga using generators), and Connect (function to bind state to view).

Additional concepts: Subscriptions (collect actions from sources like keyboard, websocket, etc.), Router (uses react‑router), and Route Components (presentational components separate from model‑connected components).

Minimal Dva Application Structure

Without Model

import dva from 'dva';
const App = () =>
Hello dva
;
const app = dva();
app.router(() =>
);
app.start('#root');

With Model

const app = dva();
app.use(createLoading());
app.model({
  namespace: 'count',
  state: 0,
  reducers: {
    add(state) { return state + 1; }
  },
  effects: {
    *addAfter1Second(action, { call, put }) {
      yield call(delay, 1000);
      yield put({ type: 'add' });
    }
  }
});
app.router(() =>
);
app.start('#root');

Underlying Implementation

Dva consists of two packages: dva (high‑order component layer using react‑redux) and dva-core (model layer using redux‑saga).

The dva function creates an app object, proxies router and start , and connects the view layer. It sets up history, middleware, and renders the React tree.

export default function (opts = {}) {
  const history = opts.history || createHashHistory();
  const createOpts = { /* ... */ };
  const app = create(opts, createOpts);
  const oldAppStart = app.start;
  app.router = router;
  app.start = start;
  return app;
  function router(router) { /* ... */ }
  function start(container) { /* ... */ }
}

The dva-core create function builds the app instance, exposing use , model , and start . The start method initializes the Redux store, registers reducers and sagas, runs subscriptions, and provides model management APIs.

export function create(hooksAndOpts = {}, createOpts = {}) {
  const { initialReducer, setupApp = noop } = createOpts;
  const plugin = new Plugin();
  plugin.use(filterHooks(hooksAndOpts));
  const app = { _models: [prefixNamespace({ ...dvaModel })], _store: null, _plugin: plugin, use: plugin.use.bind(plugin), model, start };
  return app;
}
function start() { /* store init, saga run, subscriptions */ }

Comparison with React, React‑Redux, and Redux‑Saga

React alone requires lifting state to common ancestors. React‑Redux extracts state into a store, connects components via connect , and enables middleware interception. Redux‑Saga handles asynchronous side‑effects as middleware. Dva unifies store, saga, and model concepts, adds subscriptions, and offers a concise DSL‑like API.

frontendReduxState ManagementReactSagaDVA
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.