Data Client

Async State Management without the Management
Alternatives To Data Client
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Zustand35,601101,3362 days ago113August 01, 20231mitTypeScript
🐻 Bear necessities for state management in React
Mobx26,7369,2674,4205 days ago241July 18, 202343mitTypeScript
Simple, scalable state management.
Jotai15,0793892 days ago150July 31, 20234mitTypeScript
👻 Primitive and flexible state management for React
Boardgame.io9,6593224a month ago203November 10, 202294mitTypeScript
State Management and Multiplayer Networking for Turn-Based Games
Awesome React Hooks9,251
2 months ago9cc0-1.0
Awesome React Hooks
Rematch8,4012101567 days ago76November 09, 202123mitTypeScript
The Redux Framework
React Final Form7,2825006284 months ago76April 01, 2022390mitJavaScript
🏁 High performance subscription-based form state management for React
Mobx State Tree6,7814793856 days ago109March 10, 2023125mitTypeScript
Full-featured reactive state management without the boilerplate
Router5,147135 days ago15March 21, 202226mitTypeScript
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Easy Peasy4,99937577 days ago261July 28, 202312mitJavaScript
Vegetarian friendly state for React
Alternatives To Data Client
Select To Compare


Alternative Project Comparisons
Readme

Reactive Data Client

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

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
Popular State Management Projects
Popular Reactjs Projects
Popular User Interface Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Typescript
Reactjs
Rest
Fetch
State Management
Reactive Programming