roz333 :
I've created a simple shopping app which has three screens including: Home
, Book Store
and Cart
screens
I am using redux for updating all states, Everything works smoothly except one thing. I want the users when click on items in Cart
they get removed one by one but the problem is that when i click on one item all of them get removed simultaneously
How can i fix this?
Reducer code:
import {
ADD,
REMOVE
} from '../actions/types';
const initialState = {
items: [],
counter: 0
}
export const cardReducer = (state = initialState, action) => {
switch (action.type) {
case ADD:
return {
...state, items: state.items.concat({
name: action.payload.name,
index: Math.random(),
price: action.payload.price,
id: action.payload.id
}), counter: state.counter + 1 }
break;
case REMOVE:
return {
...state,
items: state.items.filter((item) => {
item.index !== action.payload
}), counter: state.counter - 1 }
break;
default:
return state;
}}
Action code:
import {
ADD,
REMOVE
} from './types';
export const addSomething = (item) => {
return {
type: ADD,
payload: item
}}
export const removeSomething = (index) => {
return {
type: REMOVE,
payload: index
} }
And this is the Cart
screen codes:
import { useDispatch, useSelector } from 'react-redux';
import { addSomething, removeSomething } from '../actions';
const Cards = (props) => {
const { navigation } = props;
const dispatch = useDispatch();
const items = useSelector(state => state.cardR.items)
return (
<View style={{ alignItems: 'center', flex: 1 }}>
<View style={{ width: '80%' }}>
<FlatList
data={items}
keyExtractor={(item, index) => index}
renderItem={({ item, index }) => (
<TouchableOpacity
style={styles.button}
activeOpacity={0.7}
onPress={(index) => dispatch(removeSomething(item.index))}
>
<Text style={{ color: 'white' }}>{item.name}</Text>
<Text style={{ color: 'white' }}>{item.price}</Text>
</TouchableOpacity>
)} />
</View>
</View>
)}
Kundan Singh Chouhan :
The problem seems in the index
property, likewise @giotskhada has mentioned in his response. The possible solution could be to check the removable item with its id
instead of the index, which is already there to uniquely identify the each item.
Try this instead -
Reducer Code:
case REMOVE:
return {
...state,
items: state.items.filter((item) => {
return item.id !== action.payload // Id instead of index and return statement
}),
counter: state.counter - 1
}
break;
Cart Screen Code:
<TouchableOpacity
style={styles.button}
activeOpacity={0.7}
onPress={(index) => dispatch(removeSomething(item.id))}> // id instead of index
<Text style={{ color: 'white' }}>{item.name}</Text>
<Text style={{ color: 'white' }}>{item.price}</Text>
</TouchableOpacity>