ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Relay EntryPointContainer 完全指南:以 render-as-you-fetch 模式渲染预加载的 EntryPoint

Relay EntryPointContainer 完全指南:以 render-as-you-fetch 模式渲染预加载的 EntryPoint 前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载EntryPointContainer是 RelayJavaScript 数据驱动 React 应用框架中用于渲染预加载 EntryPoint 的 React 组件它接收由loadEntryPoint或useEntryPointLoader产生的 EntryPoint 引用并挂载对应 EntryPoint 的根组件。本文以 Relay v18 的 API 参考文档为核心结合仓库内react-relay包的实际源码与配套 API 文档系统讲解EntryPointContainer的签名、参数语义、底层渲染实现、配套的数据预加载 API 以及完整可运行的使用示例帮助读者正确落地 render-as-you-fetch 模式并规避内存泄漏。一、EntryPointContainer是什么EntryPointContainer是 React 组件其唯一职责是渲染一个已经完成预加载preloaded的 EntryPoint。它并不负责触发数据加载而是消费预加载的结果——这一设计对应 Relay 的 render-as-you-fetch 模式先在用户交互如路由跳转、点击事件发生时提前发起数据与代码块chunk的加载再将加载完成的引用交给容器组件渲染。根据官方 API 参考entrypoint-container.md其函数签名如下function EntryPointContainer({ entryPointReference, props, }: { entryPointReference: PreloadedEntryPointTEntryPointComponent, props: TRuntimeProps, }): ReactElement从签名可以看出组件只接收两个 propsentryPointReference与props这正是 EntryPoint 渲染机制的核心——预加载的数据、代码与渲染所需的运行时参数在此汇合。二、参数详解2.1entryPointReference类型PreloadedEntryPointTEntryPointComponent来源依据官方文档由loadEntryPoint函数调用返回或通过useEntryPointLoaderhook 获取。该对象封装了 EntryPoint 完成预加载后的全部信息从源码 EntryPointTypes.flow.js 可见其结构export type PreloadedEntryPointTEntryPointComponent Readonly{ dispose: () void, entryPoints: ElementConfigTEntryPointComponent[entryPoints], extraProps: ElementConfigTEntryPointComponent[extraProps], getComponent: () TEntryPointComponent, isDisposed: boolean, queries: ElementConfigTEntryPointComponent[queries], rootModuleID: string, };其中queriesEntryPoint 关联的已预加载查询PreloadedQuery集合会被原样传递给根组件entryPoints嵌套子EntryPoint 的预加载引用集合实现 EntryPoint 的递归嵌套extraProps由.entrypoint.js文件中getPreloadProps返回的额外属性集合getComponent获取 EntryPoint 根组件的函数内部处理 JSResource 的按需加载与 ES Module 解包dispose释放引用、允许关联数据被垃圾回收的方法isDisposed标记该引用是否已被释放。2.2props类型TRuntimeProps语义依据官方文档额外的运行时 props将原样透传给 EntryPoint 的根Component。典型场景包括事件回调如onClick处理函数、当前页面状态等只有到组件渲染阶段才存在的值——它们与预加载阶段就确定的queries、entryPoints、extraProps相互区分三者共同构成根组件的完整 props见 EntryPointTypes.flow.js 的EntryPointProps类型定义。三、源码级实现剖析EntryPointContainer的实现非常精简完整逻辑见 EntryPointContainer.react.js其核心流程可拆解为四步3.1 已释放引用的防御性警告组件在渲染前会检查entryPointReference.isDisposed若为true则发出警告第 44-50 行Expected entryPointReference to not be disposed yet. This is because disposing the entrypoint marks it for future garbage collection, and as such may no longer be present in the Relay store. In the future, this will become a hard error.这提醒开发者不要对已经dispose()的引用继续渲染否则未来版本将升级为硬错误。因此在实际开发中卸载组件或切换页面时应避免在已释放引用上调用EntryPointContainer。3.2 解构引用并解析根组件const {getComponent, queries, entryPoints, extraProps, rootModuleID} entryPointReference; const Component getComponent();getComponent由loadEntryPoint内部实现见 loadEntryPoint.js若 EntryPoint 根模块JSResource尚未加载它会触发entryPoint.root.load()并抛出加载 Promise供 React Suspense 捕获若已加载则直接返回组件并对{default: module}形式的 ES Module 包装进行解包。3.3 记录消费日志useEffect(() { environment.__log({ name: entrypoint.root.consume, profilerContext, rootModuleID, }); }, [environment, profilerContext, rootModuleID]);组件挂载时会通过 Relay Environment 的__log记录一条entrypoint.root.consume内部日志第 56-62 行携带 Profiler 上下文与根模块 ID供性能分析与内部观测使用。3.4 渲染根组件并透传 propsreturn ( Component entryPoints{entryPoints} extraProps{extraProps} props{props} queries{queries} / );可见EntryPointContainer本质上是薄壳它把容器 props 中的props与预加载得到的queries、entryPoints、extraProps汇聚后一起透传给根组件。TypeScript 声明EntryPointContainer.react.d.ts通过条件类型GetRuntimePropsFromComponent自动从PreloadedEntryPoint的组件类型中推导出props的类型保证类型安全。四、如何获得entryPointReference两个配套 APIEntryPointContainer本身只消费引用引用的产生依赖以下两个 API分别有独立 API 文档load-entrypoint.md 与 use-entrypoint-loader.md。4.1 命令式loadEntryPointloadEntryPoint专为配合EntryPointContainer实现 render-as-you-fetch 而设计签名含 Flow 泛型为function loadEntryPointTEntryPointParams, TPreloadedQueries, TPreloadedEntryPoints, TRuntimeProps, TExtraProps, TEntryPointComponent, TEntryPoint( environmentProvider: IEnvironmentProviderEnvironmentProviderOptions, entryPoint: TEntryPoint, entryPointParams: TEntryPointParams, ): PreloadedEntryPointTEntryPointComponent三个核心参数environmentProvider提供 Relay Environment 实例的对象含getEnvironment方法在 React 组件内通常传入useRelayEnvironment()得到的 environment 包装而成entryPoint要加载的 EntryPoint通常通过导入*.entrypoint.js文件获得entryPointParams传给 EntryPointgetPreloadProps方法的参数如路由参数、查询变量。加载行为官方文档明确调用时EntryPoint 关联的每个查询都会同时加载查询数据与查询 AST两者都就绪后数据才写入 store——这与已废弃的prepareEntryPoint_DEPRECATED不同后者要等到用usePreloadedQuery渲染时才写入数据。从源码 loadEntryPoint.js 可见其内部会并行处理三类加载启动根模块JSResource的代码加载遍历getPreloadProps返回的queries逐一调用loadQuery支持fetchPolicy、networkCacheConfig、includeIf等PreloadOptions配置includeIf false的查询会跳过预加载遍历entryPoints递归调用loadEntryPoint加载嵌套子 EntryPoint。重要提示官方文档loadEntryPoint返回的引用会让关联查询数据被 Relay store 持续保留阻止垃圾回收必须在其不再被引用时调用.dispose()释放否则会造成数据泄漏。因此官方建议只要有可能就优先使用useEntryPointLoader。另外loadEntryPoint在 React 渲染阶段调用会抛出错误。4.2 声明式 HookuseEntryPointLoaderuseEntryPointLoader把 EntryPoint 引用保存在 state 中并在其不再可访问时自动dispose()从根本上避免数据泄漏实现见 useEntryPointLoader.js。返回值为三元组entryPointReference当前预加载引用未加载时为nullloadEntryPoint加载回调参数为TEntryPointParams加载新引用前会自动释放旧的disposeEntryPoint置空并释放当前引用的回调。其内部实现相当考究第 88-106 行的注释说明了设计动机由于setState不保证每次都触发 commithook 用一个Set追踪所有调用过loadEntryPoint的引用在 commit 阶段useEffect逐一释放未成为当前引用的旧引用并在 hook 卸载时兜底释放全部剩余引用。五、完整实战示例结合useEntryPointLoader文档use-entrypoint-loader.md中的示例一个完整的 render-as-you-fetch 用法如下const {useEntryPointLoader, EntryPointContainer} require(react-relay); const ComponentEntryPoint require(Component.entrypoint); function EntryPointRevealer(): React.MixedElement { const environmentProvider useMyEnvironmentProvider(); const [ entryPointReference, loadEntryPoint, disposeEntryPoint, ] useEntryPointLoader(environmentProvider, ComponentEntryPoint); return ( { entryPointReference null ( Button onClick{() loadEntryPoint({})} Click to reveal the contents of the EntryPoint /Button ) } { entryPointReference ! null ( Button onClick{disposeEntryPoint} Click to hide and dispose the EntryPoint. /Button Suspense fallbackLoading... EntryPointContainer entryPointReference{entryPointReference} props{{}} / /Suspense / ) } / ); }该示例体现的实践要点渲染阶段用 hookuseEntryPointLoader自动管理生命周期无需手写disposeSuspense 包裹由于 EntryPoint 根模块与查询数据可能仍在加载需将EntryPointContainer置于Suspense边界内加载期间展示 fallback交互触发加载点击按钮时才调用loadEntryPoint数据与代码块的请求与渲染解耦达到 render-as-you-fetch 的效果运行时 props 透传props{...}中可传入点击回调、页面参数等运行时信息最终作为props传给根组件。如果必须在事件处理器中命令式加载则需手动维护生命周期官方 load-entrypoint.md 给出的模式是const EntryPoint require(MyComponent.entrypoint.js); // 通常在组件内通过 useRelayEnvironment 获取 environment const getEntrypointReference environment loadEntryPoint( { getEnvironment: () environment }, EntryPoint, {id: 4}, ); // 稍后把 entryPointReference 传给 EntryPointContainer // 注意示例省略了 .dispose() 调用实际使用必须释放引用六、与 EntryPoint 类型系统的关系从类型层面理解EntryPointContainer有助于正确使用。.entrypoint.js文件的规范结构见 EntryPointTypes.flow.js要求导出对象包含两个必填字段getPreloadProps(entryPointParams)根据参数返回PreloadPropsqueries、entryPoints、extraPropsroot指向根组件的JSResourceReference。而根组件须符合EntryPointComponent类型第 166-179 行其接收的四类 props 与EntryPointContainer透传的内容一一对应根组件 props来源说明queriesgetPreloadProps返回的queries已预加载的查询PreloadedQuery集合entryPointsgetPreloadProps返回的entryPoints已预加载的嵌套 EntryPointextraPropsgetPreloadProps返回的extraPropsEntryPoint 文件中定义的额外属性包propsEntryPointContainer的propsprop渲染时的运行时属性这一对称设计意味着预加载阶段能确定的一切queries/entryPoints/extraProps都提前备好只有运行时才存在的值props在渲染时传入EntryPointContainer正是连接这两个阶段的关键桥梁。七、实践注意事项与常见陷阱切勿渲染已 dispose 的引用EntryPointContainer会对isDisposed true的引用发出警告未来将升级为硬错误命令式加载务必手动 dispose使用loadEntryPoint时引用不在需要后必须调用.dispose()否则关联查询数据会被 Relay store 持续保留造成内存泄漏useEntryPointLoader会自动处理优先选用不要在渲染阶段调用loadEntryPoint官方文档明确渲染阶段调用会抛错应在事件回调或useEffect中触发配合 Suspense 使用EntryPoint 根模块代码块与查询数据可能仍在传输中必须用Suspense包裹容器组件并提供 fallback嵌套 EntryPoint 的递归释放dispose()是递归的——释放父 EntryPoint 时其内部通过嵌套加载的子 EntryPoint 引用以及它们的查询数据也会一并释放见 loadEntryPoint.js。八、延伸阅读EntryPointContainer配套 APIloadEntryPoint、useEntryPointLoader源码实现EntryPointContainer.react.js、loadEntryPoint.js、useEntryPointLoader.js、EntryPointTypes.flow.js类型声明EntryPointContainer.react.d.ts相关 hookuseRelayEnvironment、usePreloadedQuery赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐Relay 15 的 EntryPointContainer以 render-as-you-fetch 模式渲染预加载 EntryPoint 的权威指南Relay 15 的 EntryPointContainer以 render as you fetch 模式渲染预加载 EntryPoint 的权威指南 导读前端开发工具Relay EntryPointContainer 完全指南渲染预加载 EntryPoint 与 render-as-you-fetch 实践Relay EntryPointContainer 完全指南渲染预加载 EntryPoint 与 render as you fetch 实践 导读 Entr前端开发工具Relay EntryPointContainer 详解渲染预加载 EntryPoint 的根组件与 render-as-you-fetch 实践Relay EntryPointContainer 详解渲染预加载 EntryPoint 的根组件与 render as you fetch 实践 导读 En前端开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表