ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

wp-calypso Query Posts 数据查询组件指南:React 声明式文章数据获取实战

wp-calypso Query Posts 数据查询组件指南:React 声明式文章数据获取实战 前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载Query Posts 是 WordPress.com 前端应用 wp-calypso 中用于管理文章Posts查询与数据拉取的核心 React 组件。它通过零渲染的声明式设计将文章列表 / 单篇文章 / 全站文章三类网络请求抽象为简单的组件挂载行为配合全局 Redux 状态树完成数据的获取与共享。读完本文你将掌握该组件的全部 Props 语义、底层 action 调用链、防重复请求机制以及它在统计模块中的真实落地用法。组件定位与核心设计理念Query Posts 位于 client/components/data/query-posts/是 wp-calypso Query 组件家族client/components/data/下还有 query-post-stats、query-jetpack-modules 等同系列组件中的一员负责所有文章类数据的前端拉取。它遵循一个非常鲜明的设计原则组件不接收任何 children也不向页面渲染任何 DOM 元素。组件挂载的唯一职责是发起数据请求而请求结果统一落入全局应用状态Redux store由挂载在同一层级的兄弟组件通过 selector 消费。这种请求组件与展示组件分离的模式让数据获取逻辑可以在任何页面位置复用而不必关心视图层如何渲染。从源码 index.jsx 可以看到组件的渲染函数直接return null其全部逻辑都发生在useEffect中function QueryPosts( { siteId, postId, query } ) { const dispatch useDispatch(); const memoizedQuery useMemoCompare( query, isShallowEqual ); useEffect( () { dispatch( request( siteId, postId, memoizedQuery ) ); }, [ dispatch, siteId, postId, memoizedQuery ] ); return null; }组件使用 React Hooks 实现useDispatch获取 Redux 的 dispatch 能力useEffect在 Props 变化时触发请求而useMemoCompare来自 client/lib/use-memo-compare/index.ts配合wordpress/is-shallow-equal对query对象做浅比较保证只有 query 内容真正变化时才重新发起请求避免因对象引用变化导致的重复拉取。基本用法在需要文章数据的页面中将QueryPosts作为兄弟组件渲染传入siteId和query。以下示例来自原文档展示了如何用它在自定义文章列表中拉取并渲染数据import QueryPosts from calypso/components/data/query-posts; import MyPostsListItem from ./list-item; export default function MyPostsList( { posts } ) { return ( div QueryPosts siteId{ 3584907 } query{ { search: Themes } } / { posts.map( ( post ) { return MyPostsListItem key{ post.global_ID } post{ post } /; } ) } /div ); }注意QueryPosts本身不产出任何可见 UIposts数据是通过 connect/useSelector 从全局状态中读取的组件只是确保请求已被发出、数据已就绪。post.global_ID是 wp-calypso 状态树中文章的全局唯一标识用于列表 key。Props 详解siteId项值类型Number是否必填否默认值null需要查询文章的站点 ID。传入后执行指定站点的文章查询若不传为null则退化为当前用户所有站点的全局文章查询。postId项值类型Number是否必填否默认值null需要查询的单篇文章 ID。一旦提供组件将执行单篇文章查询而非列表查询用于获取该站点的某篇具体文章。query项值类型Object是否必填否默认值null发起文章请求时使用的查询参数对象会被原样透传给 WP.com REST API。常用参数包括search关键词搜索、number每页数量、order/order_by排序、type文章类型与status发布状态等其默认值定义在 client/state/posts/constants.jsexport const DEFAULT_POST_QUERY { context: display, http_envelope: false, pretty: false, number: 20, offset: 0, page: 1, order: DESC, order_by: date, type: post, status: publish, sticky: include, search: , };这些默认值与 API 侧语义保持一致默认拉取 20 篇已发布文章按日期倒序排列。未传入query时null组件会以空对象发起请求由 API 侧应用上述默认行为。三种数据获取模式的底层调用链QueryPosts的请求分派逻辑集中在 index.jsx 的request函数中按 Props 组合分为三条路径const request ( siteId, postId, query ) ( dispatch, getState ) { const state getState(); if ( ! siteId ! isRequestingPostsForQuery( state, null, query ) ) { dispatch( requestAllSitesPosts( query ) ); return; } if ( ! postId ! isRequestingPostsForQuery( state, siteId, query ) ) { dispatch( requestSitePosts( siteId, query ) ); return; } if ( ! isRequestingSitePost( state, siteId, postId ) postId 0 ) { dispatch( requestSitePost( siteId, postId ) ); } };三条路径的判定优先级为全站查询 → 站点列表查询 → 单篇文章查询对应关系如下Props 组合触发的 action底层 API 端点对应源文件仅query无siteId、无postIdrequestAllSitesPosts(query)GET /me/postsrequest-all-sites-posts.jssiteIdquery无postIdrequestSitePosts(siteId, query)GET /sites/{siteId}/postsrequest-site-posts.jssiteIdpostIdrequestSitePost(siteId, postId)GET /sites/{siteId}/posts/{postId}request-site-post.js前两条路径最终都汇聚到统一的 request-posts.js它负责发出网络请求并分发三类状态 actionexport function requestPosts( siteId, query {} ) { return ( dispatch ) { dispatch( { type: POSTS_REQUEST, siteId, query } ); const endpoint siteId ? /sites/${ siteId }/posts : /me/posts; return wpcom.req .get( endpoint, { ...query } ) .then( ( { found, posts } ) { dispatch( receivePosts( posts ) ); dispatch( { type: POSTS_REQUEST_SUCCESS, siteId, query, found, posts } ); } ) .catch( ( error ) { dispatch( { type: POSTS_REQUEST_FAILURE, siteId, query, error } ); } ); }; }requestSitePosts在缺少siteId时直接返回nullrequest-site-posts.js而requestAllSitesPosts等价于调用requestPosts( null, query )request-all-sites-posts.js二者语义在底层统一。单篇文章路径则独立走 request-site-post.js先分发POST_REQUEST再通过wpcom.site( siteId ).post( postId ).get()拉取单篇数据成功后用receivePost写入状态树并分发POST_REQUEST_SUCCESS失败则分发POST_REQUEST_FAILURE。防重复请求机制序列化查询 请求中标记request函数在每次分派前都会先调用 selector 检查对应请求是否已经在进行中从源头避免并发重复请求。其判断依据是 is-requesting-posts-for-query.js 与 is-requesting-site-post.js// is-requesting-posts-for-query.js export function isRequestingPostsForQuery( state, siteId, query ) { const serializedQuery getSerializedPostsQuery( query, siteId ); return !! state.posts.queryRequests[ serializedQuery ]; } // is-requesting-site-post.js export function isRequestingSitePost( state, siteId, postId ) { if ( ! siteId ) { return null; } if ( ! state.posts.siteRequests[ siteId ] ) { return false; } return !! state.posts.siteRequests[ siteId ][ postId ]; }列表查询使用序列化查询串作为状态键查询对象先经 get-normalized-posts-query.js 归一化剔除与DEFAULT_POST_QUERY相同的字段再由 get-serialized-posts-query.js 做JSON.stringify有siteId时拼接为siteId:serializedQuery形式的键。这样语义相同的查询如{ search: }与{}会命中同一个键从而正确复用请求状态。在状态层client/state/posts/reducer.js 中的两个 reducer 负责维护请求中标记queryRequests以序列化查询为键、以POSTS_REQUEST action.type为值记录列表请求状态reducer.js#L113-L125siteRequests以siteId - postId - boolean的嵌套结构记录单篇请求状态reducer.js#L90-L103。请求发出、成功、失败三类 action 都会更新对应标记确保标记在请求结束后复位下一次挂载可重新拉取。项目中的真实使用案例Query Posts 目前主要被 wp-calypso 的统计Stats模块采用覆盖周/月/邮件详情页与单篇文章详情页stats-post-detail/index.jsx{ siteId ! isPostHomepage QueryPosts siteId{ siteId } postId{ postId } / }在文章统计详情页按站点与文章 ID 拉取单篇文章供摘要与预览区域消费stats-detail-weeks/index.jsx 与 stats-detail-months、stats-email-detail同样以siteIdpostId组合挂载为周/月/邮件明细视图准备文章数据all-time-highlights-section/post-cards-group.tsxQueryPosts siteId{ siteId } postId{ topViewedPost.id } query{ {} } /在历史时刻高亮区块中按需为排名文章发起单篇查询。这些页面通常在兄弟位置同时挂载QueryPostStats文章统计与QueryPosts文章本体二者各司其职、互不干扰是请求组件与展示组件分离架构的直接体现。需要查看更多同类 Query 组件的读者可浏览 client/components/data/ 目录下的其他 README。最佳实践与注意事项放在数据消费组件的兄弟位置QueryPosts不渲染 UI务必与读取state.posts的组件平级挂载并确保消费数据的 selector如getSitePost、getPostsForQuery基于同一siteId/query取值。用post.global_ID作为列表 key列表数据来自不同站点时ID可能重复使用全局唯一标识可避免 key 冲突。query对象应保持稳定组件用浅比较判定 query 是否变化若每次渲染都新建对象会导致useMemoCompare不断更新引用并重复请求建议将查询对象提升为常量或使用useMemo。理解优先级同时传入siteId与postId时走单篇查询query参数将被忽略需要列表查询时不要传postId。全站查询的代价不传siteId会请求/me/posts当前用户全部站点的文章数据量与耗时都更大仅应在明确需要跨站点聚合时使用。请求状态已内建去重同一siteId 序列化 query 的并发挂载不会重复发请求selector 与 reducer 层已做好防重保护无需在业务侧额外加锁。综上Query Posts 通过极简的声明式 API把 wp-calypso 中文章数据从何而来的问题收敛为一个可复用的挂载动作配合 client/state/posts/ 下的 actions、selectors 与 reducer构成了完整、可预测的文章数据获取链路。赞分享前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载相关推荐深入解析 wp-calypso 的 QueryPostStats 组件文章统计数据的声明式数据获取方案深入解析 wp calypso 的 QueryPostStats 组件文章统计数据的声明式数据获取方案 导读 在 WordPress.com 的 JavaSc前端CMSwp-calypso Query Theme 组件解析单主题数据获取的声明式解决方案wp calypso Query Theme 组件解析单主题数据获取的声明式解决方案 Query Theme 是 wp calypsoWordPress.c前端CMSwp-calypso 站点统计声明式数据获取组件 QuerySiteStats 完全指南wp calypso 站点统计声明式数据获取组件 QuerySiteStats 完全指南 QuerySiteStats / 是 wp calypsoWord前端CMS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表