Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我无法使用Gatsby动态创建页面_Javascript_Reactjs_Ecmascript 6_Graphql_Gatsby - Fatal编程技术网

Javascript 我无法使用Gatsby动态创建页面

Javascript 我无法使用Gatsby动态创建页面,javascript,reactjs,ecmascript-6,graphql,gatsby,Javascript,Reactjs,Ecmascript 6,Graphql,Gatsby,我在我的项目中使用盖茨比。我正在尝试创建一个需要分页的页面 我遵循了这个和这个其他的指南以及如何做,但它不起作用 我对gatsby node.js有多个查询: exports.createPages = async ({ graphql, actions, page }) => { const { createPage } = actions const shop = path.resolve("./src/templates/shop.js")

我在我的项目中使用盖茨比。我正在尝试创建一个需要分页的页面

我遵循了这个和这个其他的指南以及如何做,但它不起作用

我对
gatsby node.js有多个查询:

exports.createPages = async ({ graphql, actions, page }) => {
    const { createPage } = actions
    const shop = path.resolve("./src/templates/shop.js")
    const productPageTemplate = path.resolve("./src/templates/ProductPage/index.js")
    
    const singleProduct = await graphql(`
      query {
        allShopifyProduct {
          edges {
            node {
              handle
            }
          }
        }
      }
    `)
    
    // This is the query which I need for the pagination
    // Create shop pages
    const products = await graphql(`
      query allShopifyProduct($skip: Int!, $limit: Int!) {
        allShopifyProduct(sort: { fields: [createdAt], order: DESC }
          skip: $skip
          limit: 5
        ) {
          edges {
            node {
              id
              title
              handle
            }
          }
        }
      }
    `)
    
    const posts = products.data.allShopifyProduct.edges  
    
    const postsPerPage = 5
    const numPages = Math.ceil(posts.length / postsPerPage)
    
    Array.from({ length: numPages }).forEach((_, i) => {
      const withPrefix = (pageNumber) =>
        pageNumber === 1 ? `/shop` : `/shop/${pageNumber}`
      const pageNumber = i + 1
      createPage({
        path: withPrefix(pageNumber),
        component: shop,
        context: {
          limit: postsPerPage,
          skip: i * postsPerPage,
          current: pageNumber,
          total: numPages,
          hasNext: pageNumber < numPages,
          nextPath: withPrefix(pageNumber + 1),
          hasPrev: i > 0,
          prevPath: withPrefix(pageNumber - 1),
        },
      })
    })
    
    // Adding the single product stuff to show my multiple queries
    singleProduct.data.allShopifyProduct.edges.forEach(({ node }) => {
      createPage({
        path: `/product/${node.handle}/`,
        component: productPageTemplate,
        context: {
          // Data passed to context is available
          // in page queries as GraphQL variables.
          handle: node.handle,
        },
      })
    })
})
如果我在GraphiQL界面上运行这些精确的查询,一切都会完美地工作:


你知道我在哪里会失败吗?

一开始。。。用于传递查询中使用的参数/值(作为变量)的方法。。。您应该在“循环”查询中将它们(值)传递给变量:

然后,您可以在整个(查询+为分页列表和单个产品创建页面)块上构建一个“外部”循环,将当前
myLoopingSkip
值传递到查询变量
skip

两种可能的循环方案

  • 一次查询所有产品(所有数据)
  • 仅查询当前迭代所需的数据段(5项记录集/数据块)
第一个选项很简单,但在大数据集上可能会消耗大量资源,有时可能会崩溃

第二个(IMHO更好)选项更可靠,但在循环之前需要额外/单独查询
numPages
(所有产品的数量)。对于条件
下一页
,它也是必需的

在现实生活中,在10页之后浏览是不寻常的。。。实际上,即使谷歌在页面限制后也会停止显示结果。。。但是,产品页面必须链接到某个可以访问/爬网的地方——依我看,最好按类别列出较短的分页列表

如果您真的不需要
numPages
,只要查询的数据(结果)包含5条记录,就可以通过添加5条(您的“限制”/
postsPerPage
)来保持循环。在这种情况下,“外环”可以如下所示:

const postsPerPage = 5;
let myLoopingSkip = 0; // starting skip
do {
  // read only data you need in current iteration
  let products = await graphql(PAGINATED_PRODUCTS_QUERY, 
    { skip: myLoopingSkip, limit: postsPerPage } );

  // paginated list
  createPage({
    path: withPrefix(pageNumber),
    component: shop,
    context: {
      limit: postsPerPage,
      skip: i * postsPerPage,
    ...      
  // but you can just pass fetched data
  // as is done for product page
  // no need for query inside component
  // just loop over `data` prop to create grid view
  //
  // createPage({
  //   path: withPrefix(pageNumber),
  //   component: shop,
  //   context: {
  //     data: products.data.allShopifyProduct.edges,

  // loop for single products pages
  products.data.allShopifyProduct.edges.map( (node) => {
    createPage({
    path: `/product/${node.handle}/`,
    component: productPageTemplate,
    context: {
      // Data passed to context is available
      // in page queries as GraphQL variables.
      handle: node.handle,
      // ... but we already have all data here 
      // ... again, no query needed
      // data: node
    }
  });

  myLoopingSkip += postsPerPage;
} while( products.data.allShopifyProduct.edges.length===postsPerPage )
// or use total page condition

您必须在
createPage
API中的上下文中提供这些变量:

  createPage({
    path: `/product/${node.handle}/`,
    component: productPageTemplate,
    context: {
      skip: 0 // or any variable
      limit: 5 // or any variable
      handle: node.handle, // is it used? If don't, you can remove it
    },
  })
由于您在查询中使用了不可为空的
跳过
限制
变量(用感叹号标记,
),因此:

它们需要存在,因此您需要(通过上下文)以与GraphQL查询相同的方式提供它们

您的
handle
变量似乎未使用,至少在提供的代码中是这样,在这种情况下,您可以删除它

有关的更多信息

let myLoopingSkip = 0; // starting skip

// Create shop pages
const products = await graphql(`
  query allShopifyProduct($skip: Int!, $limit: Int!) {
    allShopifyProduct(sort: { fields: [createdAt], order: DESC }
      skip: $skip
      limit: $limit
    ) {
      edges {
        node {
          id
          title
          handle
        }
      }
    }
  }
`,  { skip: myLoopingSkip, limit: 5 } ); // variables used in query
const postsPerPage = 5;
let myLoopingSkip = 0; // starting skip
do {
  // read only data you need in current iteration
  let products = await graphql(PAGINATED_PRODUCTS_QUERY, 
    { skip: myLoopingSkip, limit: postsPerPage } );

  // paginated list
  createPage({
    path: withPrefix(pageNumber),
    component: shop,
    context: {
      limit: postsPerPage,
      skip: i * postsPerPage,
    ...      
  // but you can just pass fetched data
  // as is done for product page
  // no need for query inside component
  // just loop over `data` prop to create grid view
  //
  // createPage({
  //   path: withPrefix(pageNumber),
  //   component: shop,
  //   context: {
  //     data: products.data.allShopifyProduct.edges,

  // loop for single products pages
  products.data.allShopifyProduct.edges.map( (node) => {
    createPage({
    path: `/product/${node.handle}/`,
    component: productPageTemplate,
    context: {
      // Data passed to context is available
      // in page queries as GraphQL variables.
      handle: node.handle,
      // ... but we already have all data here 
      // ... again, no query needed
      // data: node
    }
  });

  myLoopingSkip += postsPerPage;
} while( products.data.allShopifyProduct.edges.length===postsPerPage )
// or use total page condition
  createPage({
    path: `/product/${node.handle}/`,
    component: productPageTemplate,
    context: {
      skip: 0 // or any variable
      limit: 5 // or any variable
      handle: node.handle, // is it used? If don't, you can remove it
    },
  })
  query allShopifyProduct($skip: Int!, $limit: Int!)