自定义钩子不是函数

问题描述 投票:0回答:1

我试图让 useCart() 工作,但它说它不是一个函数

"use client";

import React, { createContext, useReducer, useContext } from "react";

const CartContext = createContext();

const cartReducer = (state, action) => {
  switch (action.type) {
    case "ADD_TO_CART":
      // Check if the item is already in the cart
      const existingItem = state.find((item) => item.id === action.payload.id);

      if (existingItem) {
        // If the item is already in the cart, update its quantity
        return state.map((item) =>
          item.id === action.payload.id
            ? { ...item, quantity: item.quantity + 1 }
            : item
        );
      } else {
        // If the item is not in the cart, add it with quantity 1
        return [...state, { ...action.payload, quantity: 1 }];
      }

    case "REMOVE_FROM_CART":
      return state.filter((item) => item.id !== action.payload.id);

    default:
      return state;
  }
};

export const CartProvider = ({ children }) => {
  const [cart, dispatch] = useReducer(cartReducer, []);

  return (
    <CartContext.Provider value={{ cart, dispatch }}>
      {children}
    </CartContext.Provider>
  );
};

export const useCart = () => {
  const context = useContext(CartContext);
  if (!context) {
    throw new Error("useCart must be used within a CartProvider");
  }
  return context;
};

我将 CartContext 包装在应用程序文件夹中的layout.js 中,并尝试在我的两个组件中使用此功能,如下所示。

const CartPage = () => {
  const { cart, dispatch } = useCart();

网站的其余部分可以工作,但是当我转到需要使用 useCart() 的页面时,我收到运行时错误。

Error: (0 , _contexts_CartContext__WEBPACK_IMPORTED_MODULE_2__.useCart) is not a function

请告诉我我做错了什么,或者在 NextJs 中是否有更好的方法来做到这一点。

我希望购物车加载到页面上,我尝试以不同的方式导出它并重新启动开发服务器,但一个小时后我无法让它工作。

reactjs next.js react-hooks client cart
1个回答
0
投票

由于您在

CartPage
组件中使用了钩子,因此需要在组件顶部添加
'use client'
指令,如下所示:

'use client'    
const CartPage = () => {
      const { cart, dispatch } = useCart();

// ...rest of your component

默认情况下,Next.js 使用服务器组件,因此如果您需要执行任何使用状态的操作,则需要使您的组件成为客户端组件。更多信息这里

© www.soinside.com 2019 - 2024. All rights reserved.