reactjs - 卡在后期预览组件中

标签 reactjs graphql gatsby algolia

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

enter image description here

我在模板文件夹中的 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
    }
  }
}

`

作品:

enter image description here

我的 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

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

最佳答案

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

之前的一些见解

在处理 Algolia + Gatsby 时,您将分页、显示/隐藏/呈现所有特定帖子等的责任委托(delegate)给 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 将默认显示所有帖子。

关于分页,您有 Pagination来自 React InstantSearch 的组件,因此您无需担心,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 中打印这些值。

基本上,您是通过属于 Algolia 的 connectSearchBox HOC 将组件“连接”到 Algolia 的 API;它将当前搜索字符串公开为 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.

结果称为“命中”,您作为 props 收到的是一个命中,因此,您的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 都向用户显示匹配搜索结果的属性。前者呈现全部值(value),而后者仅显示一个片段。片段是紧邻匹配项的文本。 attribute 属性是 Algolia 索引中键的名称(由 algolia-queries.js 中的 pageToAlgoliaRecord 生成)。

总的来说,您的页面似乎呈现了正确数量的 Postpreview 组件,但由于 hit 的解构而没有呈现正确的内容。

关于reactjs - 卡在后期预览组件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66977182/

相关文章:

带有 Graphql Apollo Server 的 graphql-tester(单元测试)

Gatsby google-tagmanager 插件 : how to access dataLayer. 推送

javascript - React 16 在返回数组时强制组件重新渲染

node.js - Apollo Client V2 获取数据的顺序错误

java - graphql-java-tools:空参数与不存在参数

javascript - 在 React Helmet/Gatsby 中插入自定义脚本

node.js - 在 Gatsby 构建期间检索文件内容

javascript - 在最后两个数字之前添加逗号并在三个数字之后保留点

javascript - TypeError : props. theTodos.map 不是函数

javascript - Array.splice 适用于两个状态子数组