我有一個對象數組addon_categories
包含一個屬性id
和另一個數組:addons
。當用戶切換複選框時,狀態應該相應更新:其中包括添加或刪除所選類別下的「addons」數組。如何通過更新對象數組中特定對象內的數組來更新狀態?
this.state = { addon_categories: [] };
// example of filled state
this.state = { addon_categories: [
{ id: 3, addons: [ 1 ] },
{ id: 2, addons: [ 1, 4, 11 ] },
{ id: 4, addons: [ 3, 4] }
] };
這是更的JavaScript
多於React
的問題的不同之處在於數據必須被最終更新爲成分的狀態。作爲JavaScript的初學者,我無法用包含一些屬性和數組的對象數組來更新狀態對象。在下面的代碼中,爲特定類別更新addons
數組(適用於刪除和推送)的正確邏輯是什麼?
這裏的邏輯:
如果類別ID不存在,簡單地增加一個新的對象與該類別ID和附加元件陣列與單個附加ID。 [✓]
如果類別ID存在,
- >檢查addon_id是否存在於此類別中。
- >如果addon_id存在於此類別中,請從此對象中的addons數組中刪除addon id [?]
- >如果addon_id不存在,請將此addon id插入此對象中的addons數組[
這是我的代碼。
import React from 'react';
import { connect } from 'react-redux';
import store from '../../../../reducers/store';
import fetchFood from '../../../../actions/restaurant/food_get';
class AddonsModal extends React.Component
{
constructor(props)
{
super(props);
this.state = { addon_categories: [] };
this.onAddonChange = this.onAddonChange.bind(this);
}
/*
* Handle click, toggle addon change
*/
onAddonChange(e)
{
const c = +e.target.name; // category_id from input
const a = +e.target.id; // addon_id from input
// create new instance of this.state.addon_categories
let addon_categories = this.state.addon_categories.slice();
if (!this.addonCategoryExists(c))
{
// CATEGORY DOESNT EXIST, SO NEW CATEGORY AND ADDON ADDED!
addon_categories.push({ id: c, addons: [a] });
this.setState({ addon_categories },() => console.log('NEW STATE', this.state.addon_categories));
}
else
{
// CATEGORY EXISTS
if (this.addonExistsInCategory(c, a))
{
// ?? ADDON EXISTS IN THIS CATEGORY, SO NEED TO REMOVE IT
}
else
{
// ?? ADDON DOESNT EXIST IN CATEGORY SO NEED TO ADD IT TO JUST THIS CATEGORY
}
}
}
addonCategoryExists(c)
{
return !! this.state.addon_categories.filter(category => category.id === c).length;
}
addonExistsInCategory(c, a)
{
let verified = false;
let categories = this.state.addon_categories.filter(category => category.id === c);
categories.forEach(category =>
{
if (category.addons.includes(a)) { verified = true; }
});
return verified;
}
componentDidMount()
{
store.dispatch(fetchFood(this.props.Restaurant.id, this.props.food.id));
}
render()
{
let food = this.props.food;
let foodData = this.props.foodDetails.food.data;
let addon_categories = foodData ? foodData.data.addon_category : null;
return (
<div className="row">
{addon_categories && addon_categories.map(category => { return (
<div className="col-xs-12" key={category.id}>
<div className="pop-up-dish-specials">
<h2>{category.name}</h2>
{category.addons && category.addons.map(addon => { return (
<div key={addon.id}>
{/* for simplicity, i've sent the category_id in name and addon_id in id property */}
<input type="checkbox" name={category.id} id={addon.id} onChange={this.onAddonChange}/>
<label htmlFor={addon.id}>{addon.name}</label>
</div>
)})}
</div>
</div>
)})}
</div>
)
}
}
function mapStateToProps(state)
{
return { foodDetails: state.foodDetails }
}
export default connect(mapStateToProps)(AddonsModal);
這是很好的解決方案,非常感謝。 – anonym
我想進一步分解兩個刪除條件。 '[#1]'刪除整個'addon_category對象',如果它是其中唯一的插件,'[#2。]'如果有多個(完成✓),就從陣列中刪除插件。我無法使用'if(category.id === c && category.addons.length === 1){return addon_categories.splice(index,1); }' – anonym
您的解決方案將無法正常工作,因爲拼接會返回已刪除的項目,因此它不會對您有所幫助。你可以做2件事 - 或者只是修改我的代碼返回到這樣的'newAddons.length? {id:category.id,addons:newAddons}:undefined',然後在設置狀態時,您將執行addon_categories:newCategories.filter(category => category)'(這樣您可以從數組中過濾一個未定義的值。這樣做是爲了保存類別索引值,然後在設置狀態之前使用splice從newCategories中刪除它。 –