By default, the export package name for all APIs in this section is: @modern-js/runtime/model.

If Reduck is integrated separately from Modern.js, the export package name is: @modern-js-reduck/react.

An asynchronous function type Effect usually has three states that need to be processed: in request, request successful, and request failed. The way to handle these states is to write the Action functions (pending, fulfilled, rejected).

With the help of the handleEffect API, we can generate default Action functions to handle different results at each stage of an asynchronous request. The structure of the State returned by the Action generated by handleEffect is as follows:

interface State {
  result: any; // result of fulfilled state
  pending: boolean; // request is pending
  error: string; // request error message

Function Signature

interface EffectActions {
  pending: Action;
  fulfilled: Action;
  rejected: Action;

interface Config {
  ns?: string;
  result?: string | false;
  error?: string | false;
  pending?: string | false;
  combineMode?: 'merge' | 'replace';
  omitResultNamespace?: boolean;

function handleEffect(config: Config): EffectActions;


  • ns: the default returned State structure is flat, By setting this parameter, the returned State can be mounted under the field named by the ns. For example, if ns is set to "data", the returned structure is:
interface State {
  data: {
    pending: boolean;
    result: any;
    error: string;
  • result: the default value is "result". This parameter corresponds to the field name that stores the fulfilled state results. For example, set result to "items", the returned State structure is:
interface State {
  items: any; // Default result -> items
  pending: boolean;
  error: string;

if result is false, then returned State has no result:

interface State {
  pending: boolean;
  error: string;
  • pending: the default value is "pending". Change the name of the pending field in the returned State. Usage is the same as result.

  • error: the default value is "error". Change the name of the error field in the returned State. Usage is the same as result.

  • combineMode: the default value is "merge". Get fulfilled state results. There are two ways to deal with it (The data types that can be automatically processed here are also limited to simple object or array types):

    • "merge": the previous data is merged with the current data. the data is an array type, operation is similar to [].concat(lastData, currentData). the data is an object, operation is similar to {...lastData, ...curData}.
    • "replace": the current data directly replaces the previous data.
  • omitResultNamespace: the default value is false. When the result is an object type, you want to mount the result directly on the State of the Model, rather than on "result", you can set it to true. For example:

// the result: {user: 'xx', email: 'xx'},
// config handleEffect({ omitResultNamespace: true })
// get State like follows:
  user: 'xx',
  email: 'xx',
  pending: false,
  error: null,

Return Type

Objects are processed by actions in pending, fulfilled, and rejected states.