簡體   English   中英

如何通過從對象數組更新特定對象內的數組來更新狀態?

[英]How do I update the state by updating an array within a particular object from an array of objects?

我有一個對象數組addon_categories包含屬性id和另一個數組: 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] }
 ] };

除了必須最終將數據作為組件狀態進行更新之外,這比React更是JavaScript的問題。 作為JavaScript的初學者,我無法使用包含某些屬性和數組的對象數組來更新狀態對象。 在下面的代碼中,僅針對特定類別更新addons數組(用於刪除和推送到)的正確邏輯是什么?

這是邏輯:

  1. 如果類別ID不存在,只需添加具有類別ID和具有單個插件ID的插件數組的新對象。 [✓]

  2. 如果類別ID存在,
    ->檢查addon_id是否在此類別中。
    ->如果此類別中存在addon_id,請從此對象中的此addons數組中刪除該插件的ID [?]
    ->如果addon_id不存在,則將此插件ID推送到該對象中的插件數組[?]

這是我的代碼。

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);
    if (this.addonExistsInCategory(c, a)) {
      // ADDON EXISTS IN THIS CATEGORY, SO NEED TO REMOVE IT
      addon_categories.find(function(obj) {
        if (obj.id == c) {
          obj.addons.splice(obj.addons.indexOf(a), 1);
        }
      });
    } else {
      // ADDON DOESNT EXIST IN CATEGORY SO NEED TO ADD IT TO JUST THIS CATEGORY
      addon_categories.find(function(obj) {
        if (obj.id == c) {
          obj.addons.push(a);
        }
      });
    }
this.setState({ addon_categories }, () => console.log('NEW STATE', this.state.addon_categories));

如果存在插件,我將只使用簡單的.map和.filter,因此將其刪除:

const newCategories = this.state.addon_categories.map(category => {
    if (category.id === c) {
        const newAddons = category.addons.filter(addon => addon !== a);
        return { id: category.id, addons: newAddons };
    } else {
        return category;
    }        
});
this.setState({ addon_categories: newCategories });

添加它是這樣的:

const newCategories = this.state.addon_categories.map(category => {
    if (category.id === c) {
        const newAddons = category.addons.concat([a])
        return { id: category.id, addons: newAddons };
    } else {
        return category;
    }        
});
this.setState({ addon_categories: newCategories });

不過,可能有更好的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM