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);
问题原因及解决方法
问题核心:
useReducerHook的返回值顺序是[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
相关产品推荐
相关产品推荐

