在创建我的 gatsby-node.js 文件并正确指示通过 graphql 动态生成的页面后,我无法查看任何详细产品

After creating my gatsby-node.js file with the pages properly instructed to be dynamically generated via graphql, I can't view any of detailed product

如果我点击某个产品,我会收到以下 404 错误:

如果我点击引导我进入上面屏幕截图中列出的 link 的前 6 个产品之一,我会收到关于我的数量未定义的错误消息,如下所示:

当我关闭错误时,我留下了这个:

再次 - 我在下面包含了我的 gatsby-node.js 以及我的 QtyButton.js 代码...我还有 linked to my github repo here with the most updated code...

盖茨比-node.js:

/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

// You can delete this file if you're not using it
exports.createPages = async({
  graphql,
  actions
}) => {
  const {
    createPage
  } = actions

  const result = await graphql(
    `
      {
        products: allStrapiProduct {
          edges {
            node {
              name
              strapiId
              description
              category {
                name
              }
              variants {
                id
                color
                size
                style
                price
                images {
                  localFile {
                    childImageSharp {
                      gatsbyImageData
                    }
                  }
                }
              }
            }
          }
        }
        categories: allStrapiCategory {
          edges {
            node {
              strapiId
              name
              description
              filterOptions {
                Size {
                  checked
                  label
                }
                Style {
                  checked
                  label
                }
                Color {
                  checked
                  label
                }
              }
            }
          }
        }
      }
    `
  )

  if (result.errors) {
    throw result.errors
  }

  const products = result.data.products.edges
  const categories = result.data.categories.edges

  products.forEach(product => {
    createPage({
      path: `/${product.node.category.name.toLowerCase()}/${
        product.node.name.split(' ')[0]
      }`,
      component: require.resolve('./src/templates/ProductDetail.js'),
      context: {
        name: product.node.name,
        id: product.node.strapiId,
        category: product.node.category.name,
        description: product.node.description,
        variants: product.node.variants,
        product,
      },
    })
  })

  categories.forEach(category => {
    createPage({
      path: `/${category.node.name.toLowerCase()}`,
      component: require.resolve('./src/templates/ProductList.js'),
      context: {
        name: category.node.name,
        description: category.node.description,
        id: category.node.strapiId,
        filterOptions: category.node.filterOptions,
      },
    })
  })
}

exports.onCreateWebpackConfig = ({
  stage,
  loaders,
  actions
}) => {
  if (stage === 'build-html') {
    actions.setWebpackConfig({
      module: {
        rules: [{
          test: /react-spring-3d-carousel/,
          use: loaders.null()
        }],
      },
    })
  }
}

QtyButton.js

import React, {
  useState,
  useEffect,
  useContext
} from 'react'
import clsx from 'clsx'
import Grid from '@material-ui/core/Grid'
import Typography from '@material-ui/core/Typography'
import Button from '@material-ui/core/Button'
import ButtonGroup from '@material-ui/core/ButtonGroup'
import Badge from '@material-ui/core/Badge'
import {
  makeStyles
} from '@material-ui/core/styles'

import {
  CartContext
} from '../../contexts'
import {
  addToCart,
  removeFromCart
} from '../../contexts/actions'

import Cart from '../../images/Cart'

const useStyles = makeStyles(theme => ({
  qtyText: {
    color: ({
      white
    }) => (white ? theme.palette.secondary.main : '#fff'),
  },
  mainGroup: {
    height: '3rem',
  },
  editButtons: {
    height: '1.525rem',
    borderRadius: 0,
    backgroundColor: ({
        white
      }) =>
      white ? '#fff' : theme.palette.secondary.main,
    borderLeft: ({
        white
      }) =>
      `2px solid ${white ? theme.palette.secondary.main : '#fff'}`,
    borderRight: ({
      round
    }) => (round ? 0 : '2px solid #fff'),
    borderBottom: 'none',
    borderTop: 'none',
    borderRadius: ({
      round
    }) => (round ? '0px 50px 50px 0px' : 0),
    '&:hover': {
      backgroundColor: ({
          white
        }) =>
        white ? '#fff' : theme.palette.secondary.light,
    },
  },
  endButtons: {
    backgroundColor: ({
        white
      }) =>
      white ? '#fff' : theme.palette.secondary.main,
    borderRadius: 50,
    border: 'none',
  },
  cartButton: {
    marginLeft: '0 !important',
    transition: 'background-color 1s ease',
  },
  minus: {
    marginTop: '-0.25rem',
  },
  minusButton: {
    borderTop: ({
        white
      }) =>
      `2px solid ${white ? theme.palette.secondary.main : '#fff'}`,
  },
  qtyButton: {
    '&:hover': {
      backgroundColor: ({
          white
        }) =>
        white ? '#fff' : theme.palette.secondary.main,
    },
  },
  badge: {
    color: '#fff',
    fontSize: '1.5rem',
    backgroundColor: theme.palette.secondary.main,
    padding: 0,
  },
  success: {
    backgroundColor: theme.palette.success.main,
    '&:hover': {
      backgroundColor: theme.palette.success.main,
    },
  },
}))

export default function QtyButton({
  stock,
  variants,
  selectedVariant,
  name,
  isCart,
  white,
  hideCartButton,
  round,
  override,
}) {
  const {
    cart,
    dispatchCart
  } = useContext(CartContext)
  const existingItem = isCart ?
    cart.find(item => item.variant === variants[selectedVariant]) :
    null
  const classes = useStyles({
    white,
    round
  })
  const [qty, setQtyState] = useState(isCart ? existingItem.qty : 1)
  const [success, setSuccess] = useState(false)

  let setQty

  if (override) {
    setQty = val => {
      override.setValue(val)
      setQtyState(val)
    }
  } else {
    setQty = setQtyState
  }

  const handleChange = direction => {
    if (qty === stock[selectedVariant].qty && direction === 'up') {
      return null
    }

    if (qty === 1 && direction === 'down') {
      return null
    }

    const newQty = direction === 'up' ? qty + 1 : qty - 1

    setQty(newQty)

    if (isCart) {
      if (direction === 'up') {
        dispatchCart(addToCart(variants[selectedVariant], 1, name))
      } else if (direction === 'down') {
        dispatchCart(removeFromCart(variants[selectedVariant], 1))
      }
    }
  }

  const handleCart = () => {
    setSuccess(true)

    dispatchCart(
      addToCart(
        variants[selectedVariant],
        qty,
        name,
        stock[selectedVariant].qty
      )
    )
  }

  useEffect(() => {
    if (stock === null || stock === -1) {
      return undefined
    }
    if (qty === 0 && stock[selectedVariant].qty !== 0) {
      setQty(1)
    } else if (qty > stock[selectedVariant].qty) {
      setQty(stock[selectedVariant].qty)
    }
  }, [stock, selectedVariant])

  useEffect(() => {
    let timer

    if (success) {
      timer = setTimeout(() => setSuccess(false), 1500)
    }

    return () => clearTimeout(timer)
  }, [success])

  return ( <
    Grid item >
    <
    ButtonGroup classes = {
      {
        root: classes.mainGroup
      }
    } >
    <
    Button classes = {
      {
        root: clsx(classes.endButtons, classes.qtyButton)
      }
    } >
    <
    Typography variant = "h3"
    classes = {
      {
        root: classes.qtyText
      }
    } > {
      qty
    } <
    /Typography> <
    /Button> <
    ButtonGroup orientation = "vertical" >
    <
    Button onClick = {
      () => handleChange('up')
    }
    classes = {
      {
        root: classes.editButtons
      }
    } >
    <
    Typography variant = "h3"
    classes = {
      {
        root: classes.qtyText
      }
    } >
    +
    <
    /Typography> <
    /Button> <
    Button onClick = {
      () => handleChange('down')
    }
    classes = {
      {
        root: clsx(classes.editButtons, classes.minusButton)
      }
    } >
    <
    Typography variant = "h3"
    classes = {
      {
        root: clsx(classes.qtyText, classes.minus)
      }
    } >
    -
    <
    /Typography> <
    /Button> <
    /ButtonGroup> {
      hideCartButton ? null : ( <
        Button onClick = {
          handleCart
        }
        disabled = {
          stock ? stock[selectedVariant].qty === 0 : true
        }
        classes = {
          {
            root: clsx(classes.endButtons, classes.cartButton, {
              [classes.success]: success,
            }),
          }
        } >
        {
          success ? ( <
            Typography variant = "h3"
            classes = {
              {
                root: classes.qtyText
              }
            } > ✓
            <
            /Typography>
          ) : ( <
            Badge overlap = "circle"
            badgeContent = "+"
            classes = {
              {
                badge: classes.badge
              }
            } >
            <
            Cart color = "#fff" / >
            <
            /Badge>
          )
        } <
        /Button>
      )
    } <
    /ButtonGroup> <
    /Grid>
  )
}

不可能遵循此代码,您粘贴的是图像而不是代码块,因此很难知道每个部分所属的位置(如果它们是在快照之间重复的部分则更难)。尝试调试并添加有趣的部分,而不是整个文件...

and when i close out of the error I am left with this

好吧,你永远不应该关闭这个问题。它需要修复,而不是忽略。

你的gatsby-node.js,在查询一堆你不使用的字段(图片、价格等)中看起来还不错。请记住,gatsby-node.js 是您创建页面并将数据发送到模板的地方,不要查询不必要的字段以避免构建时间过长。您应该在模板查询中查询这些字段。

说到关于“第一期”,如果你的产品页面没有呈现,那就是你的问题。 运行 gatsby clean 在每个试验中。

关于您的阻塞问题,正如我所说,一个是破坏您的代码,鉴于您提供的详细信息,不可能跟踪跟踪,但我会尝试类似的方法:

      <Button
        onClick={handleCart}
        disabled={stock[selectedVariant] ? stock[selectedVariant].qty === 0 : true}
        classes={{
          root: clsx(classes.endButtons, classes.cartButton, {
            [classes.success]: success,
          }),
        }}
      >

显然,在您的某些产品中,stock 对象中没有 qty 属性,这就是您的代码出错的原因。您应该拉动线程以了解该产品是否应该具有 qty 并将代码逻辑调整为该业务逻辑,而不是其他方式。上面的代码片段应该可以解决您的代码破坏问题,但您需要知道您的 Button 是否应该或不应该 qty 在这一点上。

如果您使用可选的链接插件,您可以将其简化为:

disabled={stock?.selectedVariant?.qty === 0 : true}