javascript - Trying to delete an element from an array with objects
问题描述
I want to write a reducers-function that deletes an element of an array. The array looks like that:
Array [
Object {
"category": "First Course",
"id": 0,
"name": "Feta im Backofen gratiniert",
"price": 9.8,
},
Object {
"category": "First Course",
"id": 1,
"name": "Feta gebacken in der Kruste",
"price": 9.8,
},
Object {
"category": "First Course",
"id": 2,
"name": "Frischer Oktapus",
"price": 9.8,
}]
Here is my reducer class:
const initialState = {
restaurantId:0,
cartItems:[],
tableNumber:0,
}
const reducers = (state = initialState, action) => {
switch (action.type) {
case 'UPDATE_ID':
return {
...state,
restaurantId: action.payload
};
case 'ADD_ITEM_TO_CART':
return {
...state,
cartItems:[...Object.assign([],{...state.cartItems}),action.payload.item]
};
case 'UPDATE_TABLE_NUMBER':
return{
tableNumber: action.payload
};
case 'REMOVE_ITEM_FROM_CART':
console.log(action.payload,state.cartItems);
return{
...state,
cartItems: state.cartItems.splice(action.payload,1)
}
}
return state
}
export default reducers;
When I'm calling the 'REMOVE_ITEM_FROM_CART'-case, there are different events that occure. Sometimes multiple array elements get removed and sometimes the right one gets removed. I don't know what's the problem here. I also console.log the action.payload which gives the index of the array element that I want to remove. It's always the correct payload.
EDIT: This is the component in which the action gets called:
import React from "react";
import { StatusBar } from "expo-status-bar";
import { NavigationActions } from "react-navigation";
import { ImageBackground, StyleSheet, View, Text, TextInput, TouchableOpacity } from "react-native";
import ShoppingBag from "../components/ShoppingBag";
import {connect} from 'react-redux';
class ShoppingBagScreen extends React.Component {
returnOptionsShoppingBag=()=>{
if(this.props.cartItems.length===0 ||typeof this.props.cartItems.length===undefined) {
return(
<View>
<Text style={{fontSize:20}}>Ihr Warenkorb ist leer</Text>
</View>
)
}else{
return(
<View>
<ShoppingBag shoppingBag={this.props.cartItems} onPress={this.props.deleteCartItem}/>
<Text/>
{this.viewOrderButton()}
</View>
)}
};
viewOrderButton(){
if(this.props.tableNumber>0){
return(
<View>
<TouchableOpacity >
<Text style={{fontSize:20, color:'red'}}>Kostenpflichtig bestellen</Text>
</TouchableOpacity>
</View>
)}else{
return(
<View>
<TouchableOpacity onPress={this.orderAlert}>
<Text style={{color:'red',opacity:0.3,fontSize:20}}>Kostenpflichtig bestellen</Text>
</TouchableOpacity>
</View>
)}
};
orderAlert(){
return(
alert('Bitte wählen Sie eine Tischnummer')
)
}
render() {
return (
<View style={styles.Background}>
<Text style={{fontSize:20}}>Ihre Tischnummer lautet: {this.props.tableNumber}</Text>
<Text/>
{this.returnOptionsShoppingBag()}
</View>
)
}
}
function mapDispatchToProps(dispatch){
return {
deleteCartItem: (index) => dispatch({type: 'REMOVE_ITEM_FROM_CART', payload: index})
}}
function mapStateToProps(state){
return{
cartItems: state.cartItems,
tableNumber: state.tableNumber
}
}
export default connect(mapStateToProps,mapDispatchToProps)(ShoppingBagScreen);
This is the ShoppingBag-component:
import React from 'react';
import {View,Text,TouchableOpacity} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
export default class ShoppingBag extends React.Component{
renderShoppingBag = (shoppingBag)=>{
return shoppingBag.map((item,index)=>{
return(
<View key={index} style={{flexDirection:'row'}}>
<Text style={{fontSize:20}}> {item.name} {item.price}0€ </Text>
<TouchableOpacity onPress={()=>this.props.onPress(index)}>
<Icon name='trash' size={20}/>
</TouchableOpacity>
</View>
)
})
}
render() {
return(
<View>
{this.renderShoppingBag(this.props.shoppingBag)}
</View>
)
}
}
Thanks in advance!
解决方案
首先,我建议将您的数组操作从 return 语句中提取出来。
事实上,我强烈建议在每种情况下将状态对象和数组的副本设置为您的首要任务。
case 'REMOVE_ITEM_FROM_CART':
let cartAfterRemove = [...state.cartItems];
cartAfterRemove.splice(action.payload, 1);
//to confirm successful splice;
console.log(cartAfterRemove);
let newState = {...state, cartItems: cartAfterRemove};
return newState;
}
如果你对嵌套项目不小心并且有 0 突变,redux 会变得非常时髦。您也可以发送对象的 id 而不是索引,但这需要更多的重构。
https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns <- 有一些很好的例子。
推荐阅读
- graalvm - GraalVM Polyglot 无法加载 Java 类
- flutter - 颤振导航到其他页面中的特定选项卡
- git - GitLab:防止推送分支,除非标记
- python - 对 csv 对象的列表理解
- html - 使用 Internet Explorer 的 Excel VBA 错误 462
- javascript - 如何导入有用但未使用的文件或文件夹
- python-3.x - 如何在 Windows 的 Anaconda 上的虚拟环境中安装和使用 PyOCR
- sql - 如果它是另一个字符串的子字符串,如何删除子字符串
- windows - Windows 桌面上的 Docker - 可以在逻辑驱动器上拥有 VOLUME 吗?
- c++ - 使用 Xcode 11 和 macOS Catalina (zsh) 编译后 SFML 崩溃