前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载本地数据更新Local Data Updates是 Relay 在完全不经过网络请求的前提下直接修改 Relay Store 的一类 API。本文以 Relay 19 官方文档中的 local-data-updates.md 为核心结合仓库内relay-runtime的源码实现讲解commitLocalUpdate与commitPayload两个 API 的完整用法、底层原理与适用场景。读完本文你将能够用这两个 API 对客户端本地数据或服务器已取回的数据做精细的即时更新并理解这些更新如何自动驱动 UI 重渲染。什么是本地数据更新Relay 提供了一组 API用于对 Relay Store 执行纯本地更新purely local updates——即不绑定任何服务器操作的数据修改。这类更新与 mutation、subscription 触发的更新不同它们没有对应的网络往返也不会产生乐观响应optimistic response。本地数据更新可以作用于两类数据客户端独占数据client-only data仅存在于客户端、从未从服务器获取的数据例如用户在本地草稿箱中的内容、临时 UI 状态等常规服务器数据通过 query 或 mutation 从服务器获取、已写入 Store 的普通数据。本地更新可以直接改写这些已有记录。无论修改哪一类数据Relay 都会自动通知所有订阅了相关数据的组件触发它们重新渲染——这也是本地更新无需手动刷新页面的原因。下文两个 API 分别从命令式写 Store和写入整份查询响应两个角度实现本地更新。commitLocalUpdate命令式修改 StoreAPI 签名与基本用法commitLocalUpdate接受一个environment和一个updater函数用于在 Store 上执行命令式修改。官方文档给出的完整示例如下import type {Environment} from react-relay; const {commitLocalUpdate, graphql} require(react-relay); function commitCommentCreateLocally( environment: Environment, feedbackID: string, ) { return commitLocalUpdate(environment, store { // Imperatively mutate the store here }); } module.exports {commit: commitCommentCreateLocally};commitLocalUpdate的核心特征可以归纳为三点参数极简只接收environment和updater两个参数。updater 接收一个store参数它是RecordSourceSelectorProxy接口的实例定义见 RelayStoreTypes.js 附近的StoreUpdater (store: RecordSourceProxy) void。通过该代理对象你可以对 Store 进行命令式的读写get/getRoot读取记录create创建全新记录delete删除记录并通过返回的RecordProxy调用setValue、setLinkedRecord、setLinkedRecords等写入字段。没有第二个参数与 mutation、subscription API 接受的常规 updater 和 optimistic updater 不同commitLocalUpdate的 updater不接受第二个参数。原因在于它没有关联的网络响应——常规 updater 的第二个参数是服务器响应response本地更新没有响应可供解析。自动通知重渲染任何本地数据更新都会自动通知订阅了该数据的组件并触发重渲染无需手动触发。RecordSourceSelectorProxy的存在意味着你可以创建全新的记录例如本地暂存的评论对象也可以更新或删除已有记录例如修改服务器返回的用户昵称从而拥有对 Store 的完全控制权。底层实现原理从源码看commitLocalUpdate只是一个薄封装。其完整实现在 commitLocalUpdate.jsfunction commitLocalUpdate( environment: IEnvironment, updater: StoreUpdater, ): void { environment.commitUpdate(updater); }它直接调用了 environment 的commitUpdate方法。在RelayModernEnvironment中RelayModernEnvironment.jscommitUpdate的实现是commitUpdate(updater: StoreUpdater): void { this._scheduleUpdates(() { this._publishQueue.commitUpdate(updater); this._publishQueue.run(); }); }更新被调度进RelayPublishQueueRelayPublishQueue.jscommitUpdate(updater: StoreUpdater): void { this._pendingBackupRebase true; this._pendingData.add({ kind: updater, updater, }); }也就是说commitLocalUpdate的调用链为commitLocalUpdate → environment.commitUpdate → publishQueue.commitUpdate run()最终在run()时把 updater 应用到 Store并触发一次发布通知。这也是为什么组件订阅到的数据会随之更新、进而重新渲染——发布通知沿RelayModernStore的订阅机制逐级广播。commitPayload写入整份查询响应API 签名与基本用法如果说commitLocalUpdate是逐条命令式修改commitPayload则是整体写入一份响应。它接收一个OperationDescriptor操作描述符和该查询的 payload数据负载并将其写入 Relay Store。关键点在于这份 payload会像查询的正常服务器响应一样被解析和归一化同时还会解析其中包含的 Data Driven Dependencies数据驱动依赖例如通过JSResource、requireDefer等方式传入的资源。官方文档给出的完整示例如下import type {FooQueryRawResponse} from FooQuery.graphql const {createOperationDescriptor} require(relay-runtime); const operationDescriptor createOperationDescriptor(FooQuery, { id: an-id, otherVariable: value, }); const payload: FooQueryRawResponse {...}; environment.commitPayload(operationDescriptor, payload);这个 API 的使用要点包括创建OperationDescriptorOperationDescriptor通过createOperationDescriptor创建它接收查询query和查询变量query variables两个参数。从源码看RelayModernOperationDescriptor.js该函数还会过滤掉与操作参数不匹配的输入变量并为空值填充默认值然后依次构建 request descriptor 与 operation descriptor确保写入 Store 的响应能正确关联到查询的 reader selector 与 normalization selector。类型化 payloadpayload 可以使用 Flow 类型进行标注。只需在查询上添加raw_response_type指令编译器便会生成对应的FooQueryRawResponse类型Flow 类型文件由 Relay 编译器生成从而让 payload 的字段结构得到静态类型校验。自动通知重渲染与commitLocalUpdate一样commitPayload写入数据后所有订阅相关数据的组件都会自动收到通知并重新渲染。底层实现原理commitPayload是RelayModernEnvironment上的方法RelayModernEnvironment.js其实现为commitPayload(operation: OperationDescriptor, payload: PayloadData): void { this._execute({ createSource: () RelayObservable.from({data: payload}), isClientPayload: true, operation, optimisticConfig: null, updater: null, }).subscribe({}); }注意其中isClientPayload: true这个标志它告诉执行器这份 payload 来自客户端而非网络从而走完全本地的归一化路径。createSource把 payload 包装成RelayObservable随后由OperationExecutor像处理服务器响应一样完成数据的归一化normalization与写入。仓库中的测试 RelayModernEnvironment-CommitPayload-test.js 覆盖了该方法的多种场景含raw_response_type载荷、带 DDD 资源的载荷等可作进一步参考。commitLocalUpdate 与 commitPayload 对比维度commitLocalUpdatecommitPayload核心参数environmentupdater函数OperationDescriptor 查询 payload更新粒度逐条命令式读写可创建/更新/删除记录整份查询响应整体写入数据来源无网络响应updater 无第二个参数payload 按正常查询响应解析类型支持无专门生成类型配合raw_response_type生成 Flow 类型Data Driven Dependencies不涉及可解析JSResource、requireDefer等 DDD 资源触发重渲染自动通知订阅组件重渲染自动通知订阅组件重渲染最佳实践与适用场景局部小改动用commitLocalUpdate例如在客户端创建一条临时的本地评论记录、切换某个本地开关字段、或对服务器数据做细粒度的字段修补。此时命令式 API 更轻量、意图更清晰。整份数据回填用commitPayload当你想把一份模拟的或本地缓存的完整查询响应写回 Store例如测试环境、离线缓存回放、本地预取场景commitPayload是更合适的选择——它能复用查询的归一化逻辑保持 Store 中数据的形状与服务器响应一致。类型安全涉及 payload 时务必为查询添加raw_response_type指令并复用编译器生成的 RawResponse 类型避免手写载荷结构与查询形状不一致。理解自动重渲染机制两个 API 写入后都会经由RelayPublishQueue的发布流程广播变更订阅组件自动重渲染。因此不要在 updater 中执行副作用操作保持 updater 纯函数化只做 Store 读写。更多关于本地数据的知识如 client-only 数据定义与raw_response_type用法可参考 version-v19.0.0 下的 guided-tour 文档以及relay-runtime包内 mutations 目录与 store 目录的源码与测试。赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐Relay 本地数据更新实战指南commitLocalUpdate 与 commitPayload 深入解析Relay 本地数据更新实战指南commitLocalUpdate 与 commitPayload 深入解析 本指南聚焦 Relay 中「与服务器操作无关的纯前端开发工具Relay 本地数据更新实战指南commitLocalUpdate 与 commitPayload 全面解析Relay 本地数据更新实战指南commitLocalUpdate 与 commitPayload 全面解析 本文围绕 Relay面向数据驱动 React前端开发工具Relay 本地数据更新完全指南commitLocalUpdate 与 commitPayload 实战详解Relay 本地数据更新完全指南commitLocalUpdate 与 commitPayload 实战详解 本指南系统讲解 Relay 中不依赖任何服务器操前端开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
