I want to add more than one product into the favorite screen and delete each product from there separately, But when I click on add to favorite button I can only add one product and if I add another product the product replace the previous one NOT added on.
Context Code
const initialState = {
products: ProductData,
cart: [],
FavoritesList: [],
};
const reducer = (state = initialState, action) => {
switch(action.type) {
case 'ADD_PRODUCT_TO_FAVORITE':
const product = action.payload;
const index = state.FavoritesList.findIndex(
(item) => item?.id === product?.id
);
if (index !== -1) {
return {
...state,
products: state.FavoritesList.filter((_, i) => i !== index),
};
} else {
return {
...state,
products: state.FavoritesList.concat(product,),
};
}
case 'DELETE_FAVORITE_PRODUCT':
return {
...state,
products:state.products.filter((item)=> item?.id === product?.id)
};
case 'CLEAR':
return { cart: [] }
default:
throw new Error(`unknow action.${action.type}`)
}
}
Favorite Screen Code
const Faviroute = () => {
const { favorites, products } = useCart();
const dispatch = useDispatch();
const Clear = (index) => {
dispatch({ type: "DELETE_FAVORITE_PRODUCT", index });
};
return (
<View
style={{
flex: 1,
}}
>
{(products.length === 0) ?
<View>
<Text>Just add the items you would & place your order here.</Text>
</View>
: <View style={{flex:1,}}>
{/*Card Container*/}
<ScrollView>
<View>
{products.map((item, index) => (
<View key={index}>
<Image source={item.image} />
<TouchableOpacity onPress={() => Clear(item)}>
<Image source={icons.love} />
</TouchableOpacity>
</View>
))}
</View>
</ScrollView>
</View>
}
</View>
)
}
Can anyone can help me figure out how I can easily add every single product separately into the favorite and delete each favorite product from favorite list separately?
If you would like the ADD_PRODUCT_TO_FAVORITE
action to only add a product to favorite list one-by-one, and for the DELETE_FAVORITE_PRODUCT
action to remove a product from the favorite list one-by-one then I suggest the following refactor:
DELETE_FAVORITE_PRODUCT
reducer case correctly accesses the action payload to get a defined product object to remove.state.favorites
array and not the state.products
array that is the "source of truth" of all products that can be favorited.item
to the clear
handler, make sure to consistently name this argument so it's clear what is being passed.Code:
const initialState = {
products: ProductData,
cart: [],
favorites: [],
};
const reducer = (state = initialState, action) => {
switch(action.type){
case 'ADD_PRODUCT_TO_FAVORITE':
const product = action.payload;
const favorited = state.favorites.find(
(item) => item?.id === product?.id
);
if (!favorited) {
// Not favorited, add to favorites list
return {
...state,
favorites: state.favorites.concat(product),
};
}
// Otherwise return current state
return state;
case 'DELETE_FAVORITE_PRODUCT':
const { product } = action.payload; // <-- get product from payload
const favorited = state.favorites.find(
(item) => item?.id === product?.id
);
if (favorited) {
// Favorited, remove from favorites list
return {
...state,
favorites: state.favorites.filter((item)=> item.id !== product.id)
};
}
// Otherwise return current state
return state;
case 'CLEAR':
return { ...state, cart:[] };
default:
console.log("Unhandled action", { action });
return state;
}
};
const Favorite = () => {
const { favorites, products } = useCart();
const dispatch = useDispatch();
const unfavorite = (product) => {
dispatch({
type: "DELETE_FAVORITE_PRODUCT",
payload: { product }, // <-- pass product in payload
});
};
return (
<View style={{ flex: 1 }}>
{!products.length ? (
<View>
<Text>Just add the items you would & place your order here.</Text>
</View>
) : (
<View style={{ flex: 1 }}>
<ScrollView>
<View>
{products.map((product) => (
<View key={product.id}>
<Image source={product.image} />
<TouchableOpacity onPress={() => unfavorite(product)}>
<Image source={icons.love} />
</TouchableOpacity>
</View>
))}
</View>
</ScrollView>
</View>
)}
</View>
);
};