Reactive Data Client 中 REST API 的使用指南
项目概述
Reactive Data Client 是一个强大的数据管理库,它通过声明式的方式简化了前端应用与后端 API 的交互。本文将重点介绍如何使用该库与 RESTful API 进行高效交互。
核心概念
资源(Resource)定义
在 Reactive Data Client 中,资源(Resource)代表了一组针对特定数据模型的操作方法。它由三个核心部分组成:
- 实体(Entity):定义数据模型的结构
- 模式(Schema):声明数据转换规则
- 端点(Endpoint):定义具体的 REST 操作方法
实体(Entity)的重要性
实体是一种特殊的模式,它具有主键(pk)的概念。这种设计带来了两大优势:
- 避免状态重复:确保相同数据在应用中只有单一来源
- 高性能:通过规范化存储减少不必要的渲染
实践指南
1. 定义数据模型
用户实体示例
import { Entity } from '@data-client/rest';
export class User extends Entity {
id = '';
username = '';
static key = 'User';
}
文章实体示例
import { Entity, resource } from '@data-client/rest';
import { User } from './User';
export class Article extends Entity {
slug = '';
title = '';
content = '';
author = User.fromJS();
tags: string[] = [];
createdAt = Temporal.Instant.fromEpochMilliseconds(0);
pk() {
return this.slug;
}
static key = 'Article';
static schema = {
author: User,
createdAt: Temporal.Instant.from,
};
}
export const ArticleResource = resource({
urlPrefix: 'http://test.com',
path: '/article/:slug',
searchParams: {} as { userId?: string } | undefined,
schema: Article,
paginationField: 'page',
});
关键点说明:
pk()
方法定义了实体的主键static schema
定义了字段转换规则resource()
创建了与后端交互的端点
2. 数据获取与渲染
获取单篇文章
import { useSuspense } from '@data-client/react';
import { ArticleResource } from '@/resources/Article';
export default function ArticleDetail({ slug }: { slug: string }) {
const article = useSuspense(ArticleResource.get, { slug });
return (
<article>
<h2>{article.title}</h2>
<div>{article.content}</div>
</article>
);
}
获取文章列表
import { useSuspense } from '@data-client/react';
import { ArticleResource } from '@/resources/Article';
import ArticleSummary from './ArticleSummary';
export default function ArticleList({ userId }: { userId?: number }) {
const articles = useSuspense(ArticleResource.getList, { userId });
return (
<section>
{articles.map(article => (
<ArticleSummary key={article.pk()} article={article} />
))}
</section>
);
}
useSuspense
钩子的作用类似于 await
,它会确保数据加载完成后再渲染组件。
3. 数据变更操作
创建新文章
import { useController } from '@data-client/react';
import { ArticleResource } from '@/resources/Article';
export default function NewArticleForm() {
const ctrl = useController();
return (
<Form
onSubmit={e =>
ctrl.fetch(ArticleResource.getList.push, new FormData(e.target))
}
>
<FormField name="title" />
<FormField name="content" type="textarea" />
<FormField name="tags" type="tag" />
</Form>
);
}
更新文章
import { useController } from '@data-client/react';
import { ArticleResource } from '@/resources/Article';
export default function UpdateArticleForm({ slug }: { slug: string }) {
const article = useSuspense(ArticleResource.get, { slug });
const ctrl = useController();
return (
<Form
onSubmit={e =>
ctrl.fetch(ArticleResource.update, { slug }, new FormData(e.target))
}
initialValues={article}
>
<FormField name="title" />
<FormField name="content" type="textarea" />
<FormField name="tags" type="tag" />
</Form>
);
}
删除文章
import { useController } from '@data-client/react';
import { Article, ArticleResource } from '@/resources/Article';
export default function ArticleWithDelete({
article,
}: {
article: Article;
}) {
const ctrl = useController();
return (
<article>
<h2>{article.title}</h2>
<div>{article.content}</div>
<button
onClick={() =>
ctrl.fetch(ArticleResource.delete, { slug: article.slug })
}
>
Delete
</button>
</article>
);
}
最佳实践
- 类型安全:建议使用 TypeScript 4.0 或更高版本以获得最佳类型支持
- 表单处理:示例中使用 FormData 是为了保持中立,实际项目中可根据需求选择任何表单状态管理方案
- 自动更新:所有变更操作会自动更新相关视图,无需额外请求
- 服务器组件:在服务器端渲染时,数据会变为静态且不可变
总结
Reactive Data Client 通过声明式的方式简化了 REST API 的交互,提供了强大的数据管理能力。其核心优势在于:
- 自动化的数据规范化处理
- 高效的状态管理
- 简洁的 API 设计
- 优秀的 TypeScript 支持
通过本文的介绍,开发者可以快速上手使用 Reactive Data Client 构建高效、可靠的前端应用。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考