I m practicing an e-commerce app in react and redux. While working on it I have meet an error where the console is saying "dispatch is not a function". Although redux-thunk is working fine in other action creators. But in the following action, I m getting this error.
Here is the code from product.jsx
const Product = ({ item }) => {
return (
<Container>
<Circle />
<Image src={item.img} />
<Info>
<Icon>
// ----------Here is the Event handler -------------
<ShoppingCartOutlined onClick={addToCart(item)}/>
// ------------------ end ----------------
</Icon>
<Icon>
<SearchOutlined />
</Icon>
<Icon>
<FavoriteBorderOutlined />
</Icon>
</Info>
</Container>
);
};
export default Product;
Here is the code from the action creator cart.js
import { ADD_TO_CART } from "../constatns/actionConstants";
export const addToCart = item => dispatch =>{
try {
const cartItems = [];
let alreadyInCart = false;
cartItems.forEach(cartItem => {
if(cartItem.id === item.id){
alreadyInCart = true;
cartItem.count++
}
})
if(!alreadyInCart){
cartItems.push({...item, count: 1})
}
dispatch({type: ADD_TO_CART, payload: cartItems})
} catch (error) {
console.log(error)
}
}
And here is the cart reducer
import {ADD_TO_CART} from "../constatns/actionConstants";
const cart = (state = {cartItems: []}, action) => {
if(action.type === ADD_TO_CART) {
return {...state, cartItems: action.payload}
}else {
return state
}
}
export default cart
Moreover Would one please also elaborate the difference between using <Icon onClick={() => addToCart(item)} /> and <Icon onClick={addToCart(item)} />. I somtimes get confused. And also when should I use both thses cases.
Highly looking forward, Thanks :)
Let's have a quick summary what should happen in your app.
you dispatch an action.
that action could be either an object, that goes straight to reducer.
or it can be a function definition, that goes to redux-thunk.
redux thunk gives it the dispatch function as argument, and calls it.
so, using Redux-thunk and using functions as actions (like addToCart), you also need to dispatch those actions, so,
<ShoppingCartOutlined onClick={()=>dispatch(addToCart(item))}/>
dispatch could be defined in these two ways:
1.using useDispatch hook from react-redux package.
2.using mapDispatchToProps function.
onClick prop should be a function definition, whenever a click event happens, react calls that function.
onClick={addToCart(item)} ,
addToCart(item) returns this function definition:
dispatch =>{
try {
const cartItems = [];
let alreadyInCart = false;
cartItems.forEach(cartItem => {
if(cartItem.id === item.id){
alreadyInCart = true;
cartItem.count++
}
})
if(!alreadyInCart){
cartItems.push({...item, count: 1})
}
dispatch({type: ADD_TO_CART, payload: cartItems})
} catch (error) {
console.log(error)
}
}
And this definition will be called by react, but it's wrong. because that definition should be received by redux-thunk.
onClick={() => addToCart(item)}
now the function definition called by react after click is () => addToCart(item). still wrong due to the reasons i explained above.