Получение «Экспортированные запросы выполняются только для компонентов страницы». в Gatsby при попытке сгенерировать страницы

#javascript #reactjs #gatsby #gatsby-plugin

#javascript #reactjs #gatsby #gatsby-плагин

Вопрос:

Похоже, это относительно распространенная проблема. Я пытаюсь сгенерировать страницы сообщений в блоге, но сталкиваюсь с этой ошибкой, и страницы показывают 404 при загрузке. Это означает, что они не генерируются.

Вот мой код для gatsby.node.js файла:

 exports.createPages = async ({ graphql, useStaticQuery, actions: { createPage } }) => {
    const postQuery = graphql(`
      {
        gcms {
          posts(where: { stage: PUBLISHED }) {
              id
            slug
          }
        }
      }
    `);

    const {
        gcms: { posts },
      } = useStaticQuery(postQuery);
  
    posts.forEach(({ id, slug }) =>
      createPage({
        path: `/blog/${slug}`,
        component: require.resolve(`./src/templates/PostPage.js`),
        context: {
            id: id,
            slug: slug,
        },
      })
    );
  };
  

И мой код для файла записи в блоге PostPage.js :

 /* eslint-disable react/prop-types */
import React from 'react';
import { graphql } from 'gatsby';
import Layout from "../components/layout";
//import galaxy from "../images/galaxy.jpg";
import SEO from "../components/seo";

export const postPageQuery = graphql`
  query PostPageQuery($id: ID!) {
    gcms {
      post(where: { id: $id }) {
        title
          slug
          excerpt
          postContentMarkdown
          tags
          author {
            name
            biography
          }
          seo {
            title
            description
            keywords
          }
      }
    }
  }
`;

const PostPage = ({data: {post}}) => {
    return (
        <Layout>
            <SEO
                keywords={[
                    `ui`,
                    `ux`,
                ]}
                title="Blog" />
            {post.slug}
        </Layout>
    );
};

export default PostPage;
  

Ответ №1:

Есть несколько вещей, которые привлекли мое внимание и могут решить вашу проблему.

  • Использование useStaticQuery в вашем gatsby-node.js . Вам не нужно извлекать postQuery данные с помощью перехвата статического запроса, поскольку вы используете перехват вне компонента.

  • Использование where фильтра. Согласно документации GraphQL, способ фильтрации данных заключается в использовании filter filter. Кроме того, при фильтрации отфильтрованными критериями являются строки, поэтому их необходимо заключать в кавычки.

  • Когда вы передаете поле через context API своему PostPage , вам следует избегать фильтрации для всех ваших gcms , поскольку ваш шаблон содержит информацию об этом сообщении, не требуется повторять тот же предыдущий запрос снова (то же самое, что gatsby-node.js ), это не оптимально. Я оставлю это там, так как я не знаю, как структурированы ваши данные, но они должны быть переработаны.

Применение этого к вашему коду должно выглядеть следующим образом.

gatsby-node.js:

 exports.createPages = async ({ graphql, useStaticQuery, actions: { createPage } }) => {
    const postQuery = graphql(`
      {
        gcms {
          posts(filter: { stage: "PUBLISHED" }) {
              id
            slug
          }
        }
      }
    `);

    let {posts}= postQuery.gcms;
  
    posts.forEach(({ id, slug }) =>
      createPage({
        path: `/blog/${slug}`,
        component: require.resolve(`./src/templates/PostPage.js`),
        context: {
            id: id,
            slug: slug,
        },
      })
    );
  };
  

PostPage.js:

 /* eslint-disable react/prop-types */
import React from 'react';
import { graphql } from 'gatsby';
import Layout from "../components/layout";
//import galaxy from "../images/galaxy.jpg";
import SEO from "../components/seo";

export const postPageQuery = graphql`
  query PostPageQuery($id: ID!) {
    gcms {
      post(filter: { id: $id }) {
        title
          slug
          excerpt
          postContentMarkdown
          tags
          author {
            name
            biography
          }
          seo {
            title
            description
            keywords
          }
      }
    }
  }
`;

const PostPage = ({data: {post}}) => {
    return (
        <Layout>
            <SEO
                keywords={[
                    `ui`,
                    `ux`,
                ]}
                title="Blog" />
            {post.slug}
        </Layout>
    );
};

export default PostPage;
  

Ответ №2:

В итоге я исправил это, выполнив полную перекомпозицию своего проекта с обновлением до последней версии Gatsby, для этого с помощью bare bones gatsby starter, плагин за плагином. В итоге возникла проблема с конфликтом плагинов. Я не уверен, какой именно плагин это был, но, скорее всего, это был один из этих:

gatsby-plugin-eslint , gatsby-plugin-offline , gatsby-plugin-root-import или, возможно, prop-types пакет NPM.

Ответ №3:

Я столкнулся с такой же проблемой после обновления до последней версии Gatsby.

Аналогично ответу Тафы, для меня это был конфликт плагинов. Мне еще предстояло обновить gatsby-source-strapi плагин. Обновление этого пакета до последней доступной версии решило проблему. Каким бы ни был ваш источник данных, я бы проверил, что он по-прежнему хорошо работает с Gatsby.

Таким образом, это предупреждение / сообщение об ошибке вводит в заблуждение, вы все равно можете использовать экспортированный запрос из шаблонов, как подробно описано в документации Gatsby здесь.