React+Redux电商项目报dispatch is not a function及onClick写法疑问
报错原因及修复方案
1. 为什么会报"dispatch is not a function"
有两个直接原因:
- 事件绑定写法错误:你当前写的
onClick={addToCart(item)}会在组件渲染阶段直接执行addToCart函数,而非点击时触发。addToCart是thunk类型的action creator,执行后会返回一个接收dispatch为参数的函数,此时这个返回函数没有经过redux thunk中间件处理,没有人给它传入dispatch参数,自然就会抛出dispatch不是函数的错误。 - 组件未关联Redux store:你当前的
Product组件没有注入Redux提供的dispatch方法,就算写法正确也无法正常触发action。
2. 修复步骤
步骤1:关联Redux获取dispatch能力
推荐函数组件用useDispatch Hook实现,修改product.jsx代码:
import { useDispatch } from 'react-redux' import { addToCart } from './你存放cart.js的实际路径' const Product = ({ item }) => { const dispatch = useDispatch() // 定义点击加购的处理函数 const handleAddToCart = (item) => { dispatch(addToCart(item)) } return ( <Container> <Circle /> <Image src={item.img} /> <Info> <Icon> <ShoppingCartOutlined onClick={() => handleAddToCart(item)}/> </Icon> <Icon> <SearchOutlined /> </Icon> <Icon> <FavoriteBorderOutlined /> </Icon> </Info> </Container> ); }; export default Product;
如果你习惯用connect高阶组件,也可以用下面的写法:
import { connect } from 'react-redux' import { addToCart } from './你存放cart.js的实际路径' const Product = ({ item, addToCart }) => { return ( <Container> {/* 原有代码不变 */} <ShoppingCartOutlined onClick={() => addToCart(item)}/> {/* 原有代码不变 */} </Container> ); }; export default connect(null, { addToCart })(Product);
额外优化提示:你当前
addToCartaction creator里每次都初始化了空的cartItems数组,这样每次加购都会清空之前的购物车商品,建议改为从store获取已有购物车数据,或者把加购逻辑移到reducer里处理更合理。
两种onClick写法的区别和适用场景
写法1:onClick={addToCart(item)}
- 执行逻辑:组件渲染到这一行的时候就会立即执行
addToCart(item),将函数的返回值作为点击事件的回调。如果函数没有返回值,点击时不会触发任何逻辑;如果返回的是函数(比如你当前的thunk场景),会直接执行返回函数但没有对应参数传入,就会出现你遇到的报错。 - 适用场景:仅当你调用的函数本身返回的是一个标准事件处理函数时可以用,普通业务开发场景几乎不会用到这种写法。
写法2:onClick={() => addToCart(item)}
- 执行逻辑:给onClick绑定的是一个匿名箭头函数,只有点击事件触发的时候,才会执行箭头函数内部的
addToCart(item)逻辑,不会在渲染阶段提前执行。 - 适用场景:所有需要给事件回调传递自定义参数的场景都可以用,是业务开发中最常用的事件传参写法。
内容的提问来源于stack exchange,提问作者Ali chaudhary
相关产品推荐
相关产品推荐

