使用标签筛选时Docusaurus包装组件渲染异常
问题描述
我通过BlogPostItemWrapper包装BlogPostItem组件,集成了Giscus评论组件。预期逻辑是:访问/blog文章列表页时不加载评论组件,打开单篇文章时才加载。但使用标签筛选文章时,评论输入框意外出现,不符合预期。
截图:
相关代码:
import React from 'react'; import { useBlogPost } from '@docusaurus/theme-common/internal' import BlogPostItem from '@theme-original/BlogPostItem'; import GiscusComponent from '@site/src/components/GiscusComponent'; import useIsBrowser from '@docusaurus/useIsBrowser'; export default function BlogPostItemWrapper(props) { const { metadata } = useBlogPost() const isBrowser = useIsBrowser(); const { frontMatter, slug, title } = metadata const { enableComments } = frontMatter // Workaround from https://docusaurus.io/docs/advanced/ssg for the Error 'ReferenceError: window is not defined' during the build var isCurrentUrlBlog = false if (isBrowser) { isCurrentUrlBlog = window.location.pathname === "/blog" } return ( <> <BlogPostItem {...props} /> {(enableComments && !isCurrentUrlBlog) && ( <GiscusComponent /> )} </> ); }
问题原因
你当前用window.location.pathname === "/blog"判断是否在列表页,但标签筛选后的页面路径为/blog/tags/[标签名],这个路径不等于/blog,因此!isCurrentUrlBlog会返回true,再加上文章的enableComments为true,就会触发评论组件的渲染。而且直接依赖window.location也不是Docusaurus推荐的路由判断方式。
解决方案
改用Docusaurus提供的路由钩子来精准判断当前是否为单篇博客文章页面,避免路径硬匹配的问题。
方案一:通过文章slug精准匹配路径
import React from 'react'; import { useBlogPost } from '@docusaurus/theme-common/internal' import BlogPostItem from '@theme-original/BlogPostItem'; import GiscusComponent from '@site/src/components/GiscusComponent'; import { useLocation } from '@docusaurus/router'; export default function BlogPostItemWrapper(props) { const { metadata } = useBlogPost() const location = useLocation(); const { frontMatter, slug } = metadata const { enableComments } = frontMatter // 仅当当前路径为单篇文章的路径时,才渲染评论组件 const isSingleBlogPost = location.pathname === `/blog/${slug}`; return ( <> <BlogPostItem {...props} /> {(enableComments && isSingleBlogPost) && ( <GiscusComponent /> )} </> ); }
方案二:通过路由模板判断页面类型
import React from 'react'; import { useBlogPost } from '@docusaurus/theme-common/internal' import { useRouteContext } from '@docusaurus/router'; import BlogPostItem from '@theme-original/BlogPostItem'; import GiscusComponent from '@site/src/components/GiscusComponent'; export default function BlogPostItemWrapper(props) { const { metadata } = useBlogPost() const { route } = useRouteContext(); const { frontMatter } = metadata const { enableComments } = frontMatter // 判断当前路由是否为博客文章详情页的路由模板 const isSingleBlogPost = route.path.includes('/blog/:slug'); return ( <> <BlogPostItem {...props} /> {(enableComments && isSingleBlogPost) && ( <GiscusComponent /> )} </> ); }
两种方案都能精准控制评论组件仅在单篇文章页面加载,避免标签筛选页等场景下的误渲染。
内容的提问来源于stack exchange,提问作者m19v
相关产品推荐
相关产品推荐

