卡在 post 预览组件中

stucked in the post preview component

我被卡住了,迷路了...我正在使用 gatsby-plugin-algolia,当我搜索时,空字段被过滤掉了。它们由 PostPreview 组件生成。

模板文件夹中我的 archive.js(用于列出博客文章):

imports....

// algolia search
import algoliasearch from 'algoliasearch/lite'
import { InstantSearch, SearchBox, Hits } from 'react-instantsearch-dom'
import PostPreview from '../components/postPreview/PostPreview'

const searchClient = algoliasearch(
  'MY KEY...',
  'MY KEY...'
)

const archiveTemplate = ({
  data: { allWpPost },
  pageContext: { catId, catName, catURI, categories, numPages, currentPage }
}) => {
  return (
    <Layout>
      <Wrapper>
        <BreadCrumbs
          parent={{
            uri: '/blog/todos-os-posts',
            title: 'Blog'
          }}
        />
        <ContentWrapper>
          <ArchiveSidebar catId={catId} categories={categories.edges} />
          <PageContent>
            <InstantSearch searchClient={searchClient} indexName="Gatsby">
              <SearchBox />
              <Hits hitComponent={PostPreview} />
            </InstantSearch>

            <h1 dangerouslySetInnerHTML={{ __html: catName }} />
            {allWpPost.edges.map(post => (
              <article key={post.node.id} className="entry-content">
                <StyledDate
                  dangerouslySetInnerHTML={{ __html: post.node.date }}
                />
                <Link to={`/blog${post.node.uri}`}>
                  <StyledH2
                    dangerouslySetInnerHTML={{ __html: post.node.title }}
                  />
                </Link>
                <p dangerouslySetInnerHTML={{ __html: post.node.excerpt }}></p>
                <StyledReadMore to={`/blog${post.node.uri}`}>
                  Leia +
                </StyledReadMore>
                <div className="dot-divider" />
              </article>
            ))}
            <Pagination
              catUri={catURI} // from the context
              page={currentPage}
              totalPages={numPages}
            />
          </PageContent>
        </ContentWrapper>
      </Wrapper>
    </Layout>
  )
}

export default archiveTemplate

export const pageQuery = graphql`
  query($catId: String!, $skip: Int!, $limit: Int!) {
    allWpPost(
      filter: { categories: { nodes: { elemMatch: { id: { eq: $catId } } } } }
      skip: $skip
      limit: $limit
    ) {
      edges {
        node {
          id
          title
          excerpt
          uri
          slug
          date(formatString: "DD, MMMM, YYYY", locale: "pt")
        }
      }
    }
  }
`

我的盖茨比阿尔及利亚-config.js:

require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`
})

const AlgoliaBloghQuery = `
{
  allWpPost {
    nodes {
      title
      excerpt
      id
    }
  }
}

`

作品:

我的 PostPreview 组件,我迷路了。

imports...

const Postpreview = ({ id, title, date, excerpt, uri }) => {
  return (
    <div>
      <article key={id} className="entry-content">
        <StyledDate dangerouslySetInnerHTML={{ __html: date }} />
        <Link to={`/blog${uri}`}>
          <StyledH2 dangerouslySetInnerHTML={{ __html: title }} />
        </Link>
        <p dangerouslySetInnerHTML={{ __html: excerpt }}></p>
        <StyledReadMore to={`/blog${uri}`}>Leia +</StyledReadMore>
        <div className="dot-divider" />
      </article>
    </div>
  )
}

export default Postpreview

我不知道如何获取要传递给 props 的数据,我不知道查询是否有冲突(archive.js - gatsby-config)。仅呈现阅读更多按钮。

这是一个广泛的问题,可能会出现多处错误,我将尝试回答最常见的用例,但您需要付出一些努力才能调试并找到错误。

之前的一些见解

在处理 Algolia + Gatsby 时,您将分页、show/hide/render 所有特定帖子等的责任委托给 Algolia。因此,以下部分是多余的,应删除:

        {allWpPost.edges.map(post => (
          <article key={post.node.id} className="entry-content">
            <StyledDate
              dangerouslySetInnerHTML={{ __html: post.node.date }}
            />
            <Link to={`/blog${post.node.uri}`}>
              <StyledH2
                dangerouslySetInnerHTML={{ __html: post.node.title }}
              />
            </Link>
            <p dangerouslySetInnerHTML={{ __html: post.node.excerpt }}></p>
            <StyledReadMore to={`/blog${post.node.uri}`}>
              Leia +
            </StyledReadMore>
            <div className="dot-divider" />
          </article>
        ))}
        <Pagination
          catUri={catURI} // from the context
          page={currentPage}
          totalPages={numPages}
        />

如果您没有搜索任何内容(初始状态),Algolia 将默认显示所有帖子。

关于分页,您有来自 React InstantSearch 的 Pagination 组件,因此您无需担心,Algolia 会为您处理。

所有与Algolia搜索相关的东西都必须包裹在InstantSearch组件中,否则将无法运行。


也就是说,您的 Searchbox 需要优化 Algolia 的结果,应该如下所示:

import React from "react"
import { connectSearchBox } from "react-instantsearch-dom"
import { Search as SearchIcon } from "@styled-icons/fa-solid"

export default connectSearchBox(
  ({ refine, currentRefinement, className, onFocus }) => (
    <form className={className}>
      <input
        className="SearchInput"
        type="text"
        placeholder="Search"
        aria-label="Search"
        onChange={e => refine(e.target.value)}
        value={currentRefinement}
        onFocus={onFocus}
      />
      <SearchIcon className="SearchIcon" />
    </form>
  )
)

注意:

    onChange={e => refine(e.target.value)}
    value={currentRefinement}

这些是关键行,如果有任何地方没有按预期工作,请尝试在 console.log.

中打印这些值

这里基本上是通过 connectSearchBox HOC 将组件“连接”到 Algolia 的 API,它属于 Algolia;它将当前搜索字符串公开为 currentRefinement 和一个用于更改它的函数 refine.

I don't know how to get the data to pass to the props, I don't know if the queries are conflicting (archive.js - gatsby-config). Only read more button are rendered.

结果称为“命中”,您收到的 propshit,因此,您的 PostPreview 应该如下所示:

const Postpreview = ({ hit }) => {
  console.log(hit);
  let { id, title, date, excerpt, uri } = hit;
 return (
    <div>
      <article key={id} className="entry-content">
        <StyledDate dangerouslySetInnerHTML={{ __html: date }} />
        <Link to={`/blog${uri}`}>
          <StyledH2 dangerouslySetInnerHTML={{ __html: title }} />
        </Link>
        <p dangerouslySetInnerHTML={{ __html: excerpt }}></p>
        <StyledReadMore to={`/blog${uri}`}>Leia +</StyledReadMore>
        <div className="dot-divider" />
      </article>
    </div>
  )
}

export default Postpreview

如果其余组件没问题,您将获得 hit 属性,其中包含所有需要的数据,因此您需要对其进行解构以获取数据。根据需要调试,根据需要添加尽可能多的日志。

您将在 Gatsby's docs 中找到详细示例(可以改进),其中关键组件是:

import { Link } from "gatsby"
import { default as React } from "react"
import {
  connectStateResults,
  Highlight,
  Hits,
  Index,
  Snippet,
  PoweredBy,
} from "react-instantsearch-dom"

const HitCount = connectStateResults(({ searchResults }) => {
  const hitCount = searchResults && searchResults.nbHits

  return hitCount > 0 ? (
    <div className="HitCount">
      {hitCount} result{hitCount !== 1 ? `s` : ``}
    </div>
  ) : null
})

const PageHit = ({ hit }) => (
  <div>
    <Link to={hit.slug}>
      <h4>
        <Highlight attribute="title" hit={hit} tagName="mark" />
      </h4>
    </Link>
    <Snippet attribute="excerpt" hit={hit} tagName="mark" />
  </div>
)

const HitsInIndex = ({ index }) => (
  <Index indexName={index.name}>
    <HitCount />
    <Hits className="Hits" hitComponent={PageHit} />
  </Index>
)

const SearchResult = ({ indices, className }) => (
  <div className={className}>
    {indices.map(index => (
      <HitsInIndex index={index} key={index.name} />
    ))}
    <PoweredBy />
  </div>
)

export default SearchResult

由于 Algolia 支持多个索引,SearchResult 遍历所有索引并使用 HitsInIndex 组件显示每个索引的命中。反过来,它在很大程度上依赖于 Hits component from the InstantSearch library.

PageHit 组件负责在搜索结果中显示单个页面(“命中”)。

connectStateResults 包装组件以向它们提供有关当前搜索的详细信息,例如查询、结果数量和计时统计信息。

HighlightSnippet 都向用户显示匹配搜索结果的属性。前者呈现全部价值,而后者仅显示一个片段。片段是紧邻匹配项的文本。 attribute 属性 是 Algolia 索引中的键名(由 pageToAlgoliaRecordalgolia-queries.js 中生成)。

总体而言,您的页面似乎呈现了正确数量的 Postpreview 组件,但由于 hit.

的解构而未呈现正确的内容