Reactive Data Client

无需管理的异步状态管理。「Async State Management without the Management」

CircleCI
Coverage Status
Percentage of issues still open
bundle size
npm version
PRs Welcome
Chat

Define your async methods. Use them synchronously in React. Instantly mutate the data and automatically update all usages.

For REST, GraphQL, Websockets+SSE and more

🌎 Website

📖Read The Docs  |  🏁Getting Started  | 
🎮Todo Demo  | 
🎮Github Demo  | 
🎮NextJS SSR Demo

Installation

npm install --save @data-client/react @data-client/rest @data-client/test @data-client/hooks

For more details, see the Installation docs page.

Usage

Simple TypeScript definition

class User extends Entity {
  id = '';
  username = '';

  pk() {
    return this.id;
  }
}

class Article extends Entity {
  id = '';
  title = '';
  body = '';
  author = User.fromJS();
  createdAt = Temporal.Instant.fromEpochSeconds(0);

  pk() {
    return this.id;
  }

  static schema = {
    author: User,
    createdAt: Temporal.Instant.from,
  };
}

Create collection of API Endpoints

const UserResource = createResource({
  path: '/users/:id',
  schema: User,
  optimistic: true,
});

const ArticleResource = createResource({
  path: '/articles/:id',
  schema: Article,
  searchParams: {} as { author?: string },
  optimistic: true,
  paginationField: 'cursor',
});

One line data binding

const article = useSuspense(ArticleResource.get, { id });
return (
  <article>
    <h2>
      {article.title} by {article.author.username}
    </h2>
    <p>{article.body}</p>
  </article>
);

Reactive Mutations

const ctrl = useController();
return (
  <CreateProfileForm
    onSubmit={data => ctrl.fetch(UserResource.getList.push, { id }, data)}
  />
  <ProfileForm
    onSubmit={data => ctrl.fetch(UserResource.update, { id }, data)}
  />
  <button onClick={() => ctrl.fetch(UserResource.delete, { id })}>Delete</button>
);

Subscriptions

const price = useLive(PriceResource.get, { symbol });
return price.value;

Type-safe Imperative Actions

const ctrl = useController();
ctrl.expireAll(ArticleResource.getList);
ctrl.invalidate(ArticleResource.get, { id });
ctrl.invalidateAll(ArticleResource.getList);
ctrl.setResponse(ArticleResource.get, { id }, articleData);
ctrl.fetch(ArticleResource.get, { id });

Programmatic queries

const queryTotalVotes = new Query(
  new schema.All(Post),
  (posts, { userId } = {}) => {
    if (userId !== undefined)
      posts = posts.filter(post => post.userId === userId);
    return posts.reduce((total, post) => total + post.votes, 0);
  },
);

const totalVotes = useCache(queryTotalVotes);
const totalVotesForUser = useCache(queryTotalVotes, { userId });

Powerful Middlewares

class LoggingManager implements Manager {
  getMiddleware = (): Middleware => controller => next => async action => {
    console.log('before', action, controller.getState());
    await next(action);
    console.log('after', action, controller.getState());
  };

  cleanup() {}
}

Integrated data mocking

const fixtures = [
  {
    endpoint: ArticleResource.getList,
    args: [{ maxResults: 10 }] as const,
    response: [
      {
        id: '5',
        title: 'first post',
        body: 'have a merry christmas',
        author: { id: '10', username: 'bob' },
        createdAt: new Date(0).toISOString(),
      },
      {
        id: '532',
        title: 'second post',
        body: 'never again',
        author: { id: '10', username: 'bob' },
        createdAt: new Date(0).toISOString(),
      },
    ],
  },
  {
    endpoint: ArticleResource.update,
    response: ({ id }, body) => ({
      ...body,
      id,
    }),
  },
];

const Story = () => (
  <MockResolver fixtures={options[result]}>
    <ArticleList maxResults={10} />
  </MockResolver>
);

...all typed ...fast ...and consistent

For the small price of 9kb gziped.    🏁Get started now

Features

Examples

  • Todo: GitHub | Sandbox
  • Github: GitHub | Sandbox
  • NextJS: GitHub | Sandbox

API

Reactive Applications

Define Data

主要指標

概覽
名稱與所有者reactive/data-client
主編程語言TypeScript
編程語言JavaScript (語言數: 4)
平台
許可證Apache License 2.0
所有者活动
創建於2019-02-15 03:37:05
推送於2025-10-25 01:19:00
最后一次提交2025-10-24 00:28:12
發布數1726
最新版本名稱@data-client/vue@0.2.0-beta-20251022010821-0e5f6bd2963b6deecb68b5febe71cdd3b10c801a (發布於 2025-10-22 01:21:47)
第一版名稱0.7.0 (發布於 2019-02-24 16:09:51)
用户参与
星數2k
關注者數16
派生數98
提交數4.7k
已啟用問題?
問題數228
打開的問題數3
拉請求數3082
打開的拉請求數9
關閉的拉請求數240
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?