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!)