cartSlice.js
import { createSlice } from "@reduxjs/toolkit";
const cartSlice = createSlice({
name: 'items',
initialState: {
items: []
},
reducers: {
addItem(state, action) {
console.log(
state.items.filter(item => item.id === action.payload.id)
)
console.log(
state.items.filter(item => item.id === action.payload.id) != []
)
if (true) {
let item = action.payload[0]
let count = action.payload[1]
state.items.push({ ...item, count })
} else {
console.log('asdas') //somelogic
}
},
removeItem(state, action) {
state.items = state.items.filter(item => item.id !== action.payload)
}
}
});
export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;
Here is where I dispatch action:
import { React } from 'react'
import { addItem } from '/store/cartSlice'
import { useDispatch } from 'react-redux'
import { useState } from 'react'
export default function ProductPage() {
let { state } = useLocation()
let item = state.item
const [count, setCount] = useState(1)
const dispatch = useDispatch()
const addTask = () => dispatch(addItem([item, count]))
return (
<>
<div className={classes.info}>
<h2 >{item.title}</h2>
<span className={classes.price}>{item.price}</span>
<div className={classes.quantity}>
<button onClick={() => setCount(count - 1)}
className={classes.quantityButton}>-</button>
{count}
<button onClick={() => setCount(count + 1)}
className={classes.quantityButton}>+</button>
</div>
<button className={classes.addToCartButton}
onClick={addTask}>Add to cart</button>
</div>
</>
)
}
Here is console:
item
is an object with keys title
, id
an some more. Why does the second log in addItem
returns true
and the first log returns an empty array in console?
I have only started working with Redux and don't understand how to work with state. I wanted to check if the item from action is actually in state.items
but it isn't working as expected.
why does the second log in addItem returns true first log returns an empty array in console
The empty array of the first log is the result of state.items.filter(item => item.id === action.payload.id
. action.payload
is an array so the id
property is undefined. The result array is empty because all item.id
values are defined and not equal to undefined
.
The second log outputs true
because you are comparing two object references, one array/object reference isn't equal to another different array/object reference.
Consider the following:
const foo = [];
const bar = foo;
console.log("[] == []", [] == []); // false
console.log("[] != []", [] != []); // true
console.log("foo == bar", foo == bar); // true
console.log("foo != bar", foo != bar); // false
I wanted to check if the item from action is actually in
state.items
but it isn't working
Update the reducer logic to correctly reference the passed item
payload value.
Examples:
Using the current array payload
dispatch(addItem([item, count]))
const [item, count] = action.payload;
state.items.filter(el => el.id === item.id);
Using an object payload
dispatch(addItem({ item, count }))
const { item, count } = action.payload;
state.items.filter(el => el.id === item.id);
If you are trying to first check if state.items
already contains the item you can search the array.
Example:
addItem(state, action) {
const [item, count] = action.payload;
const foundItem = state.items.find(el => el.id === item.id);
if (foundItem) {
// item found, update it
...
} else {
// item not found, add to state.items
// maybe -> state.items.push({ ...item, count }) 🤷🏻♂️
...
}
},