Reputation: 35
so I'm trying to dispatch a few objects and then display them. The problem is instead of adding new object to array, I'm overwriting them and it changes to a new one. So, I have a few products which are separate objects. I'm pushing them to an array and dispatching an array here:
function Product({ id, title, image, price, rating }) {
const [items, setItems] = useState([]);
const dispatch = useDispatch();
useEffect(() => {
dispatch(
pushItems({
items,
})
);
console.log(items);
}, [items]);
return (
<div className="product">
<div className="product__Info">
<p>{title}</p>
<p className="product__Info__price">
<small>$</small>
<strong>{price}</strong>
</p>
<div className="product__Info__rating">
{Array(rating)
.fill()
.map((_, i) => (
<p>⭐</p>
))}
</div>
</div>
<img src={image} alt="" />
<button
onClick={(e) =>
setItems({
title,
image,
price,
rating,
})
}
>
Add to basket
</button>
</div>
);
}
and that's how my reducer looks like, where I think the problem is:
import { createSlice } from "@reduxjs/toolkit";
const checkoutSlice = createSlice({
name: "checkout",
initialState: {
items: null,
},
reducers: {
pushItems: (state, action) => {
state.items = [...state.items, action.payload.items];
},
},
});
export const { pushItems } = checkoutSlice.actions;
export const selectItems = (state) => state.checkout.items;
export default checkoutSlice.reducer;
I know how to do it in an "old way", but when I'm using slices I'm kinda confused.
Upvotes: 0
Views: 1075
Reputation: 281686
Your Product component, doesn't need to store items array, you can directly update the items array in redux store
function Product({ id, title, image, price, rating }) {
const dispatch = useDispatch();
const onAddItem = (item) => {
dispatch(pushItems({item}));
}
return (
<div className="product">
<div className="product__Info">
<p>{title}</p>
<p className="product__Info__price">
<small>$</small>
<strong>{price}</strong>
</p>
<div className="product__Info__rating">
{Array(rating)
.fill()
.map((_, i) => (
<p>⭐</p>
))}
</div>
</div>
<img src={image} alt="" />
<button
onClick={(e) =>
onAddItem({
title,
image,
price,
rating,
})
}
>
Add to basket
</button>
</div>
);
}
Also note that state updation inside redux-toolkit
slice doesn't need to take care of immutability as it internally used immer
.
You can update your redux state like below:
const checkoutSlice = createSlice({
name: "checkout",
initialState: {
items: null,
},
reducers: {
pushItems: (state, action) => {
state.items.push(action.payload.item);
},
},
});
Upvotes: 2