Reputation: 870
I have an action which is to be used to add an object to the end of an array, but when I trigger the onPress that will run the action it always comes back with an error item.image not found
, That means it isn't seeing the newly added object's property image
, Please what I'm I doing wrong and why isn't it adding the object with the properties to the array
The Action
export const addCart = newItem => ({type:
"ADD_CART", payload: newItem
});
THE REDUCER AND INITIAL STATES
const initialState = {
cartItems: [{
image: 'img/lappy.png',
name: 'Hand Bag',
amount: '100000',
id: 4
}]
};
const rootReducer = (state = initialState, action) => {
case ADD_CART:
return{
...state,
cartItems: [...state.cartItems, action.newItem]
};
THE BUTTON THAT TRIGGERS THE ACTION
constructor(props) {
super(props);
this.state = {
name: '',
amount: '',
description: '',
qty: '',
images: [],
id: ''
};
}
carter(){
this.props.addCart(
{image: this.state.images[0],
name: this.state.name,amount:
this.state.amount,
id: this.state.id});
}
<TouchableNativeFeedback onPress={this.carter.bind(this) }>
<View style={styles.addToCart}>
<Text style={{fontSize: 14, fontFamily: 'mont-medium', color: '#fff'}}>
ADD TO CART
</Text>
</View>
</TouchableNativeFeedback>
ITEMS, i.e items.images
const cartItems = (
<FlatList
data={this.props.cartItems}
renderItem={({ item, index }) => (
<View style={styles.productbox}>
<TouchableNativeFeedback onPress={() =>
this.props.navigation.navigate('ProductDetail', {})}>
<Image resizeMode="contain" style={{borderRadius: 3,
width: 90,
height: 69,
marginLeft: '9%'}}
source={{uri: 'http://10.0.2.2:8000/'+item.image}}/>
</TouchableNativeFeedback>
<View style={styles.productTextBox}>
<Text style={styles.productName}>
{item.name}
</Text>
<Text style={styles.productPrice}>
₦{item.amount}
</Text>
</View>
<View style={styles.chatter}>
<Image resizeMode="contain" style={{alignSelf: 'center', flex: 1}}
source={require('../chatter.png')}/>
</View>
<TouchableNativeFeedback onPress={() =>this.props.removeCart(index)}>
<View style={styles.chatter2}>
<Image resizeMode="contain" style={{alignSelf: 'center', flex: 1,}}
source={require('../cancel.png')}/>
</View></TouchableNativeFeedback>
</View>
)}
keyExtractor={(item, index) => index}
/>
);
Upvotes: 1
Views: 83
Reputation: 33984
The correction is required in reducer. In actions you are returning newItem as payload but in reducer you are accessing action.newItem Instead of action.payload which is incorrect
Add below change in reducer and try
case ADD_CART:
return{
...state,
cartItems: [...state.cartItems, action.payload]
};
Also in ITEMS add below change
<FlatList
data={this.props.cartItems}
renderItem={( item, index) => (
Upvotes: 2
Reputation: 31024
Your action is dispatching an object with this shape:
{
type: "ADD_CART", payload: newItem
}
That means in your reducer you should get the new data via:
action.payload
And not:
action.newItem
So the correct reducer should look like this:
case ADD_CART:
return{
...state,
cartItems: [...state.cartItems, action.payload]
};
Upvotes: 1
Reputation: 1119
I think you misunderstood the use of the bind
function. As the doc says:
The bind() method creates a new function that, when called, has its this keyword set to the provided value
Thus, here, when you press the button, you are not calling the method, but creating a new one. You should move the bind
call to the constructor
(and don't forget to assign its return value!) and simply do this onPress={this.carter}
to call your function on press.
Maybe it would be wise to add some log in your code to see what's happening, redux can get quite confusing in the beginning :)
Upvotes: 0