【问题标题】:stucked in the post preview component卡在后期预览组件中
【发布时间】:2021-07-02 17:47:16
【问题描述】:

我被卡住了,迷路了...我正在使用 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")
        }
      }
    }
  }
`

我在 Gatsby-config.js 中的 Algolia:

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

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

【问题讨论】:

    标签: reactjs graphql gatsby algolia


    【解决方案1】:

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

    之前的一些见解

    在处理 Algolia + Gatsby 时,您将分页、显示/隐藏/渲染所有某些帖子等的责任委托给 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

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

    结果,称为“命中”,您收到的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 都向用户显示匹配搜索结果的属性。前者呈现完整值,而后者仅显示一个 sn-p。 sn-p 是紧接在匹配项周围的文本。 attribute 属性是 Algolia 索引中键的名称(由 pageToAlgoliaRecordalgolia-queries.js 中生成)。

    总体而言,您的页面似乎正在呈现正确数量的 Postpreview 组件,但由于 hit 的解构而未呈现正确的内容。

    【讨论】:

    • 我爱你 Ferran 啊哈哈哈。帖子现在完美显示。但所有帖子都有这个链接:localhost:8000/blogundefined。我会搜索看看出了什么问题。非常感谢!
    • 我忘记在 gatsby-config.js algolia 查询中添加日期和 uri。下一个挑战,按类别过滤。
    猜你喜欢
    • 2022-10-15
    • 2021-11-12
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2019-10-29
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多