首页 > 解决方案 > 通过用户输入 gatsbyJS + Firebase 显示过滤产品列表

问题描述

我正在使用 gatsby 和 firebase 构建产品目录,我想根据用户选择的产品类别显示产品列表。我会获取所有产品添加分页,现在我需要一个过滤器菜单或选择,所以我尝试了这个来实现一个过滤器..在一切正常之前......

imports
...

// query

export const data = graphql`
  query data($skip:Int!, $limit:Int!) {
   products: allProducts(
     skip: $skip, 
     limit: $limit, 
     sort: {fields: id, order: ASC}) {
    edges {
      node {
        id
        slug
        categories
        model
        previewImg
        description
        category
      }
    }
  }
}
`

//component

class ProductsSectionTemplate extends Component {
   constructor(props){
     super(props)
        this.state={
          products:[],
          product:''
        }
     }

     handleChange = event => {
        this.setState({ value: event.target.value });
     };
     handleChangeProduct = event => {
        this.setState({ product: event.target.value });
     };

     getUnique(arr, comp) {
       const unique = arr
          //store the comparison values in array
         .map(e => e[comp])

         // store the keys of the unique objects
         .map((e, i, final) => final.indexOf(e) === i && i)

         // eliminate the dead keys & store unique objects
         .filter(e => arr[e])

         .map(e => arr[e]);

        return unique;

      }
      componentDidMount(){
        const products = data.products.edges.map( product => ({
          ...product.node,
           previewImg: product.node.previewImg,
           category:product.node.category
        }))

        this.setState({
          products: products
        })
      }

   render(){
      const { pageContext} = this.props
      const products = this.state.products
      const product = this.state.product
      const { currentPage, numPages } = pageContext
      const isFirst = currentPage === 1
      const isLast = currentPage === numPages
      const prevPage = currentPage - 1 === 1 ? "/" : (currentPage - 1).toString()
      const nextPage = (currentPage + 1).toString()

      const uniqueProduct = this.getUnique(this.state.products, "category");
      const filterDropdown = products.filter( result => result.category === product );

     return(
       <Layout>
         <h1>Productos</h1>
         <select
              value={this.state.product}
              onChange={this.handleChangeProduct}
            >
              {uniqueProduct.map(product => (
                  <option key={product.id} value={product.category}>{product.category}</option>
              ))}
         </select>
          <ProductsSection products={filterDropdown}/>
          {!isFirst && (
            <Link to={`/products/${prevPage}`} rel="prev">
              ← Previous Page
            </Link>
          )}
          {Array.from({ length: numPages }, (_, i) => (
            <Link key={`pagination-number${i + 1}`} to={`/products/${i === 0 ? "" : i + 1}`}>
              {i + 1}
            </Link>
          ))}
          {!isLast && (
            <Link to={`/products/${nextPage}`} rel="next">
              Next Page →
            </Link>
          )}
       </Layout>
     )
   }
}

...

我得到的是一个错误,上面写着:

TypeError:无法读取未定义的属性“边缘”

ProductsSectionTemplate.componentDidMount

 }
  59 | componentDidMount(){
> 60 |   const products = data.products.edges.map( product => ({
  61 |     ...product.node,
  62 |      previewImg: product.node.previewImg,
  63 |      category:product.node.category

这是 gatsby-node.js 文件:

const path = require('path')

exports.createPages = async ({graphql, actions}) => {
  const { createPage } = actions

  const products = await graphql(`
     {
      allProducts (sort: {fields: id, order: ASC}, limit: 100){
        edges {
          node {
            id
            slug
            model
            description
            categories
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) throw result.errors;

    const productNodes = result.data.allProducts.edges;

    return productNodes.map( edge =>{
      return {
        ...edge.node
      }
    })
  })

  const productsPerPage = 6
  const numPages = Math.ceil(products.length / productsPerPage);

  Array.from({length:numPages}).forEach((_, i)=>{
    createPage({
      path: i === 0 ? '/products' : `/products/${i + 1}`,
      component: path.resolve('./src/templates/ProductsSectionTemplate.js'),
      context: {
        products,
        limit:productsPerPage,
        skip: i * productsPerPage,
        numPages,
        currentPage: i + 1,
      }
    });
  })

  products.forEach( product => {
    createPage({
      path: `/${product.slug}`,
      component: path.resolve('./src/templates/singleProduct.js'),
      context: {
        product
      }
    });
  });
}

谁能帮我把这个工作正常..?

感谢您的建议,问候

标签: reactjsgatsby

解决方案


您的查询可能返回未定义的一个原因可能是您的 graphQL 变量不包含任何值。

您只能将 graphQL 中的变量用于页面查询。为此,您需要在 gatsby-node.js 中定义上下文变量,如官方文档中所述:

posts.forEach(({ node }, index) => {
  createPage({
    path: node.fields.slug,
    component: path.resolve(`./src/templates/blog-post.js`),
    // values in the context object are passed in as variables to page queries
    context: {
      title: node.passThisVariable, 
    },
  })
})

如果这不能回答您的问题,请使用您的gatsby-node.js代码编辑您的问题。


推荐阅读