You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Context API中dispatch不是函数错误排查求助

React Context API中dispatch不是函数的错误解决

错误信息

Uncaught TypeError: dispatch is not a function at removeFromCart (CheckoutProduct.js:11:1)

相关代码

CheckoutProduct.js

import "./CheckoutProduct.css";
import { useStateValue } from "./StateProvider";

function CheckoutProduct({ id, title, image, price, rating }) {
  const [dispatch] = useStateValue();

  console.log(id, title, image, price, rating);

  const removeFromCart = () => {
    dispatch({
      type: "REMOVE_FROM_CART",
      id: id,
    });
  };

  return (
    <div className="checkoutProduct">
      <img className="checkoutProduct__image" src={image} alt="" />

      <div className="checkoutProduct__info">
        <p className="checkoutProduct__title">{title}</p>

        <p className="checkoutProduct__price">
          <small>₹</small>
          <strong>{price}</strong>
        </p>

        <div className="checkoutProduct__rating">
          {Array(rating)
            .fill()
            .map((_, i) => (
              <p>⭐</p>
            ))}
        </div>

        <button onClick={removeFromCart}>Remove from Cart</button>
      </div>
    </div>
  );
}

export default CheckoutProduct;

reducer.js

const initialState = {
  cart: [
    {
      id: "12345",
      title: "Versace T-Shirt",
      price: 4999,
      image:
        "https://www.versace.com/dw/image/v2/ABAO_PRD/on/demandware.static/-/Sites-ver-master-catalog/default/dw5f8ee257/original/90_E73GAHT11-ECJ00T_E899_16_PieceNumberLogoT-Shirt-T-shirtsandPolos-versace-online-store_0_2.jpg?sw=450&sh=632&sm=fit&sfrm=jpg&cksizes=380w",
      rating: 3,
    },
    {
      id: "12345",
      title: "Versace T-Shirt",
      price: 4999,
      image:
        "https://www.versace.com/dw/image/v2/ABAO_PRD/on/demandware.static/-/Sites-ver-master-catalog/default/dw5f8ee257/original/90_E73GAHT11-ECJ00T_E899_16_PieceNumberLogoT-Shirt-T-shirtsandPolos-versace-online-store_0_2.jpg?sw=450&sh=632&sm=fit&sfrm=jpg&cksizes=380w",
      rating: 3,
    },
  ],
  user: null,
};

const reducer = (state, action) => {
  console.log(action);
  switch (action.type) {
    case "ADD_TO_CART":
      return {
        ...state,
        cart: [...state.cart, action.item],
      };
    case "REMOVE_FROM_CART":
      let newCart = [...state.cart];

      const index = state.cart.findIndex(
        (cartItem) => cartItem.id === action.id
      );

      if (index >= 0) {
        //remove
        newCart.splice(index, 1);
      } else {
        console.warn(
          `Can't remove product (id: ${action.id} as its not in cart)`
        );
      }
      return {
        ...state,
        cart: newCart,
      };
    default:
      return state;
  }
};

export default reducer;

StateProvider.js(根据图片内容还原)

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

// 创建全局Context
export const StateContext = createContext();

// 状态提供器组件,包裹应用根组件
export const StateProvider = ({ reducer, initialState, children }) => (
  <StateContext.Provider value={useReducer(reducer, initialState)}>
    {children}
  </StateContext.Provider>
);

// 自定义Hook,用于获取状态和dispatch方法
export const useStateValue = () => useContext(StateContext);

问题原因及解决方法

  • 问题核心:useReducer Hook的返回值顺序是[state, dispatch],你在CheckoutProduct中错误地只解构了第一个值(即state)并命名为dispatch,导致调用时dispatch实际是状态对象而非函数。

  • 修复代码:修改CheckoutProduct中的解构语句,调整顺序或忽略未使用的state:

// 方法1:不需要用到state时,直接忽略第一个值
const [, dispatch] = useStateValue();

// 方法2:需要用到state时,正确解构
const [state, dispatch] = useStateValue();

修改后dispatch将正确指向分发动作的函数,调用removeFromCart时就不会再触发类型错误。

内容的提问来源于stack exchange,提问作者Jayesh Patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:50:34