reactjsnext.jszustandtanstacktanstack-table

zustand hook is called inside cell table tanstack


I am trying to call hooks I created with zustand to one of the cells of tanstack table, during building, eslint throws an error

Error: React Hook "useCartStore" is called in function "cell" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".  react-hooks/rules-of-hooks

cell: ({ row }) => {
  const product = row.original
  const productId = product.id
  // Get cart from store to find the current quantity
  const cart = useCartStore((state) => state.cart)
  const updateQuantity = useCartStore((state) => state.updateQuantity)
  const removeItem = useCartStore((state) => state.removeFromCart)

  // Find items in the cart
  const cartItem = cart.find((item) => item.id === productId)
  // Use cart quantity if available, otherwise use the product's default quantity
  const quantity = cartItem ? cartItem.quantity : product.quantity

what's the best way to get around from this? since cell is not a react component


Solution

  • You're getting that error because you're calling useCartStore inside the cell method which is not a React functional component. The way you can solve this is to create a functional component and abstract the logic inside the cell method into this component and then render it inside the Table cell. Below is how you can achieve this:

    export const ProductCell = ({ product }: { product: TProduct }) => {
      const productId = product.id
      // Get cart from store to find the current quantity
      const cart = useCartStore((state) => state.cart)
      const updateQuantity = useCartStore((state) => state.updateQuantity)
      const removeItem = useCartStore((state) => state.removeFromCart)
    
      // Find items in the cart
      const cartItem = cart.find((item) => item.id === productId)
      // Use cart quantity if available, otherwise use the product's default quantity
      const quantity = cartItem ? cartItem.quantity : product.quantity
    
      return (
       //The Table Cell JSX
      );
    };
    

    And in your Table columns, you call the component like this:

    {
    
       cell: ({ row }) => <ProductCell product={row.original} />
    },
    

    PS: My code implementation assumes that you're using TypeScript. If you're not using TypeScript in your project, then you can get rid of the TProduct type.