Отображение коллекции насыщенного форматированного текста с помощью Gatsby

Я создаю проект Gastby, который использует Contentful для извлечения данных. В следующем примере я пытаюсь отобразить коллекцию форматированных текстов.

import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import { INLINES, BLOCKS, MARKS } from "@contentful/rich-text-types"
import { renderRichText } from "gatsby-source-contentful/rich-text"

const LogosGQL = () => {
  const data = useStaticQuery(query)
  const firstRichContent = data.allContentfulAboutUs.nodes

  return (
    <div>
      {firstRichContent.map((page, index) => {
        renderRichText(page.content, options)
      })}
    </div>
  )
}
const options = {
  renderMark: {
    [MARKS.BOLD]: text => <b className = "font-bold">{text}</b>,
  },
  renderNode: {
    [INLINES.HYPERLINK]: (node, children) => {
      const { uri } = node.data
      return (
        <a href = {uri} className = "underline">
          {children}
        </a>
      )
    },
    [BLOCKS.HEADING_1]: (node, children) => {
      return <h1>{children}</h1>
    },
  },
}

const query = graphql`
  {
    allContentfulAboutUs {
      nodes {
        content {
          raw
        }
        contentful_id
      }
    }
  }
`

export default LogosGQL

Ошибка, которую я вижу, заключается в следующем:

Error in function renderRichText in ./node_modules/gatsby-source-contentful/rich-text.js:14
Cannot read properties of null (reading 'raw')

./node_modules/gatsby-source-contentful/rich-text.js:14
Open in Editor
  12 | // @ts-check
  13 | function renderRichText({
> 14 |   raw,
     |  ^
  15 |   references
  16 | }, options = {}) {
  17 |   const richText = JSON.parse(raw); // If no references are given, there is no need to resolve them

Я знаю, что что-то не так, когда я пытаюсь сопоставить свой массив узлов, потому что, когда я пытался отобразить только одну запись,

const LogosGQL = () => {
  const data = useStaticQuery(query)
  const firstRichContent = data.allContentfulAboutUs.nodes[0].content

  return <div>{renderRichText(firstRichContent, options)}</div>
}

Я смог увидеть вывод, правильно отображаемый на моем экране. Однако мне нужен форматированный текст из всех моих элементов. Разве сопоставление массива узлов не подходит в этом случае?

Возможно ли, что некоторые из ваших content не имеют raw данных? Как вы сказали, [0] работает, но работает ли это для всех позиций?

Ferran Buireu 28.03.2022 08:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
1
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая, что следующий фрагмент работает:

const LogosGQL = () => {
  const data = useStaticQuery(query)
  const firstRichContent = data.allContentfulAboutUs.nodes[0].content

  return <div>{renderRichText(firstRichContent, options)}</div>
}

Кажется, что некоторые из raw данных content узла неправильно установлены в некоторых узлах, потому что подход точно такой же.

Попробуйте использовать:

 {firstRichContent.map((page, index) => {
    console.info(index);
    renderRichText(page.content, options)
  })}

Чтобы увидеть оскорбительную позицию

Кроме того, из-за того, что useStaticQuery хук гидратируется, возможно, что в случаях использования данные приходят null (или пустые), попробуйте также использовать:

 {firstRichContent && firstRichContent.map((page, index) => {
    console.info(index);
    renderRichText(page.content, options)
  })}

Если приведенный выше фрагмент работает (это означает, что ваш код ломается в текущем сценарии), это означает, что выборка данных не является проблемой, и проблема находится в одной из позиций content или raw.

В этом случае, чтобы обойти эту обнуляемость, вам просто нужно:

 {firstRichContent.map((page, index) => {
    if (page.content){
       renderRichText(page.content, options)
    }
  })}

Интересно, что console.info дает следующий результат: 0 1 2 3 4 0 1 2 3 4 означает, что массив повторяется дважды. Любая идея, почему это происходит? К сожалению, последний фрагмент кода не работает (вижу точно такую ​​же ошибку)

Pavlos Rousoglou 28.03.2022 08:52

Я предполагаю, что это из-за использования useStaticQuery. в зависимости от вашей структуры React, LogosGQL может быть загружен дважды в жизненном цикле React (т. е. один раз при первой загрузке и еще один при переходе на другую страницу) (отметьте gatsbyjs.com/docs/static-VS-Normal-запросы). Фрагмент в моем ответе (firstRichContent && firstRichContent.map()) указывает, что индекс 5 является оскорбительным, и благодаря тройному условию мы знаем, что выборка данных выполнена правильно. Дважды проверьте, как настроен 5-й узел, и убедитесь, что он опубликован (используйте localhost:8000/___graphql)

Ferran Buireu 28.03.2022 08:56

Реализация индекса 5 действительно была проблемой. Кажется, теперь все работает нормально. Спасибо за ваши ответы!!

Pavlos Rousoglou 28.03.2022 09:22

Другие вопросы по теме