@ forge-go/ 客户端反应
反应绑定 @forge-go/client-core三根钩子和一个
提供商, 1.07 kB gzipped.
一切决定 什麽 价值是——身份、僵硬、分化,
无效性——是在核心中决定的,在没有渲染器的情况下可以测试.
剩下的是满足的狭隘工作 useSyncExternalStore是因为
合同没有取消任何合同.
import { useQuery, useMutation } from '@forge-go/client-react';
import { useOrderList, useOrderCreate } from './generated/hooks';
function Orders() {
const { data, status, error, isFetching, refetch } = useQuery(useOrderList, {
query: { status: 'open' },
});
const create = useMutation(useOrderCreate);
if (status === 'pending') return <Spinner />;
return (
<>
<button disabled={create.isPending} onClick={() => create.mutate({ body: { total: 0 } })}>
New order
</button>
{create.status === 'error' && <Warning error={create.error} />}
<ul>{data?.map((order) => <Row key={order.id} order={order} />)}</ul>
</>
);
}
mutate 从不拒绝: 失败 status 财务报告和审定财务报表 error,则
承诺解决 undefined这是故意的, 这就是为什么处理者
上面需要没有 .catch。记录错误的突变 财务报告和审定财务报表 拒绝
请每个召唤者记取一个--每个被遗忘的-- .catch 是一个
unhandledrejection 每写作失败, 生产中意味着提示射击
关于用户已经查看的错误.
当您在写完之后需要按顺序工作时,如果没有,则不得继续工作 要求拒绝姓名:
await create.mutateAsync({ body: { total: 0 } }); // throws on failure
router.push('/orders');
两者记录相同状态. 唯一的区别是谁是失败的主人.
第一个参数是生成物的绑定 hooks.ts
(单位:千美元)export const useOrderList = query(ops.orderList)),这是一个模块级
常数。 没有每个端点的钩子可以生成 也没有再生
当此软件包改变时.
配置客户端
configureClient() 从核心本身就够了:
import { configureClient, RestTransport } from '@forge-go/client-core';
import { entities } from './generated/ops';
import { client } from './generated/rest';
configureClient({ transport: new RestTransport({ client }), entities });
ClientProvider 实值 选项并故意这样做。 生成 hooks.ts
(a) 早在应用程序存在之前就将任何东西交给模块范围;
要求提供者将意味着从 Go 路由表重生的文件
决定消费性应用如何进行依赖性注射。 打开一个
一个全局是错误的答案——服务器同时处理两个请求,a
测试,不能漏入下一个, 应用程序对两个
后端 :
<ClientProvider client={cache}>
<App />
</ClientProvider>
决议是明确的,然后提供,然后是全球性的: useQuery(op, args, {client})
击败供应商,击败 configureClient三个都没有,
getClient() 扔出一个名称而不是刻出一个抓取缓存,什么也没有
别人也看得出来.
它的保证
- 每个查询一个请求,而不是每个组件. 两个部分呼叫
useQuery(useOrderList)是一个缓存条目,一个注册挂载和一个 请求。 他们一起定居. - 写给
Order:7只重写参考文献Order:7。 。 。 . 没有 无效在组件中被写入; 服务器已声明 . - 一个不变的实体在反射处保留其对象身份,所以一个
memo'会排出它跳过。 集装箱没有保证:新鲜的 反应是一种新鲜的骨架,商店并不声称知道 列表的形状不变。 身份在身份已知的地方得到保障. - 严格模式的挂载 / 卸载 / 挂载 , 叶片完全是一个活订阅 并且不会引起第二次请求——关于套接字和查询.
live每个呼叫站点都选择进入,并在下面共享. 两个组件在 相同的实时查询是 1 订阅; 2 不同 实时查询 使用同一通道的实体是一个连接.
刷新您不持有的查询
useQuery 手举起 refetch 用于打开该组件的查询。 当
写别的地方,使用 useInvalidate数字 :
import { useInvalidate, useMutation } from '@forge-go/client-react';
import { useOrderArchive, useOrderList } from './generated/hooks';
function ArchiveDialog({ id, onDone }: { id: number; onDone: () => void }) {
const archive = useMutation(useOrderArchive);
const invalidate = useInvalidate();
return (
<button
onClick={async () => {
await archive.mutateAsync({ path: { id } });
invalidate(useOrderList);
onDone();
}}
>
Archive
</button>
);
}
你给行动起名,从不给部件起名. useOrderList 是模块级
生成的常数 hooks.ts,所以对话框导入它想要的读取
清新和保持无知 任何列表 碰巧显示它.
三种说法:
invalidate(useOrderList); // every cached variant
invalidate(useOrderGet, { path: { id: 7 } }); // that one exactly
invalidate.tags(['Order[]', 'Order:7']); // the tag graph directly
不通过参数而覆盖每页,过滤并排序缓存所控
通常你的意思是,一旦一个字落地。 过
参数,你得到一个查询 他们按键,同一个键 useQuery 计算
当其他组件打开时。 一个皱纹. invalidate(op) 财务报告和审定财务报表
invalidate(op, {}) 不为同一查询命名, 因为一个读取了没有
参数与空对象调用的参数不同
不争辩的表 覆盖两者.
invalidate 标记查询暂停和返回。 挂载在下一条
组合成一回合
请求。 卸载者保留旗子,在下次登上时进行反射,所以
在路径中列出您在返回之前 避免了成本成本
对它.
须等时取名相求:
await archive.mutateAsync({ path: { id } });
await invalidate.refetch(useOrderList);
onDone();
火柴一解决就解决了
是一个对话框关闭之前想要的 .
它拒绝失败,像 mutateAsync 和与 mutate。未挂载匹配
保持懒惰。 查找二十个缓存过滤器组合
20项申请将毫无意义.
到达 tags 您的操作声明 provides这是
运行时间本身的模型, 它保留在服务器上的决定 其中的chema
活着 大部分生成的今天没有声明,所以可以调用的形式
按操作处理查询,并工作到标记图是否有边缘
来点新鲜的.
useInvalidate(cache) 使用相同的覆盖 useClient 夺去,并解决
同样的方式,没有了一个,所以你无效 通过你读到的缓存。 这个
只要缓存稳定,就可以放回去
或把它交给一个 memo'孩子'.
实时查询
const { data } = useQuery(useOrderList, { query: { status: 'open' } }, { live: true });
它订阅每个频道的列表 绑定到这个查询的实体
结果类型可以包含,并在最后一个消费者卸载时释放出. A 类
框架直接更新存储, 所以 order.updated 没有要求.
专访,每个呼叫网站,故意. 自动就更少了 字符和两个更糟糕的属性: 开发者读取组件不能 更长的时间显示它是否持有套接字, 以及应用程序的连接数 将成为造物树的产物.
live 是一个普通道具,所以它可能会改变。 正在尝试订阅或发行
并且确实 无 至查询——无再挂载、无回移、无装入状态.
打开它并不能掩盖它关闭的窗口:新鲜是
缓存的业务,和 live 不是一个隐藏的还原触发器。 差距
真正的是运行时间的过错,一个被丢弃的套接字被核心回收.
它需要一个流跑时间——a StreamBinder 建在同一缓存上.
没有一个人, {live: true} 通过缓存报告 onError 而不是说
静悄悄地递回一个从未更新的查询 .
服务器渲染
import { HydrationBoundary } from '@forge-go/client-react';
<HydrationBoundary state={state} ops={ops}>
<OrderTable />
</HydrationBoundary>
state 这是什么 dehydrate 在服务器上生产 ops 是生成的
操作表直接通过. hydrate 需要它是因为缓存
记录有 OperationMeta 晚点再换一个.
它在制成过程中而不是在作用中水合物. 儿童阅读
getSnapshot 在它们自己做成的过程中, 发生在此组件之后
使返回,所以在第一次通过时,它们可以看到一个变相水合物.
在树下行走之后, 效果是: 第一个涂料是装入
分枝再翻 是一个明显的闪光 水合通道上,
完全匹配组件中要删除的 。 它不包含
由于包装会改变DOM 双方
正在比较中.
严格Mode双接力渲染,所以边界可以记起它的载荷 已经水合到缓存中 。 标记已经设定 之后 水分 成功, 从未有过 : 重试一个抛出的渲染, 然后先标记 使孩子们成为 虽然它已经奏效.
getServerSnapshot 现在读取 QueryCache.peek,它返回什么
缓存保存时没有打开它从未见过的查询记录 。 这么说吧
renderToString 发出真正的标记,其中边界使缓存在
组件,以及 idle 在那里没有人这样做。 双方同意无论哪种方式,这就是
属性 反应实际检查.
拒绝有效载荷的处理方式是理性的,而不是电文。 校长
不匹配重推, 因此您的错误边界会抓住它
挂载。 通过缓存报告版本或操作不匹配
onError 和树使上, 因为两者都通过查询修复
仅仅为自己取取 并空白一页 通过每次部署
比问题更严重 任何无法识别的重播.
还没做什么
德发道具.
同伴依赖关系
两种反应 财务报告和审定财务报表 @forge-go/client-core 是同龄人,而不是依赖关系。 两个
复制的 React 表示向错误的渲染器发送的钩子. 两份
核心表示两个模块级缓存,因此应用程序配置的客户端
它产生的钩子不是从同一个缺陷中读取的,而是从下面一层.
反应18和19都得到了支持和测试.