0

To the React gods down here, I'd like to know if my code can be improved.

The goal is to add/update an array of objects nested in an object.

Here is the main object:

const initialProductData = {
        _id: "",
        name: "",
        description: "",
        type: "",
        sold: true,
        source: "",
        parents: [],
        isSubmitting: false
    };

    const [productData, setProductData] = useState(initialProductData);

All the values but parents come from a regular form and there's no problem updating them.

For the parents array, I have a function triggered by onChange on an input field that receives the event and an object coming from the row of a react-data-table-component table.

The objects added to the parents array are like:

const parent_obj = {
        parent_id: "",
        parent_product: "",
        qty_needed: ""
    }

What I need to do is:

  • add that object+value of field if it's not in the parent array yet.
  • update the object if it's already in the parent array

What I have so far that works is:

const handledParent = (event, row) => {
        let existing_parent = false;
        for (let i = 0; i < productData.parents.length; i++) {
            if (productData.parents[i].parent_id === row.id) {
                existing_parent = true;
                break;
            }
        }

        if (existing_parent) {
            setProductData({
                ...productData,
                parents: productData.parents.map((parent) => {
                    if (parent.id === row.id) return [
                        ...productData.parents,
                        {
                            parent_id: row.id,
                            parent_product: row.product,
                            qty_needed: event.target.value
                        }];
                    return {
                        ...parent,
                        qty_needed: event.target.value
                    };
                })
            })
        }
        else {
            setProductData({
                ...productData,
                parents: [
                    ...productData.parents,
                    {
                        parent_id: row.id,
                        parent_product: row.product,
                        qty_needed: event.target.value
                    }
                ]
            });
        }
    }

Am I making things over complicated ? Is there a way to do that with a single setProductData() ?

Thanks for your feedback.

PYG
  • 347
  • 1
  • 2
  • 8

2 Answers2

1

You can try something like this :

const handledParent = (event, row) => {
        // return the object's index if it exist or -1if not
        let indexFound = productData.parents.findIndex((parent) =>parent.parent_id === row.id);

        let parentsArray = productData.parents;
// if parent exist in the productData array
        if(indexFound !== -1){
        let parent = {...parentsArray[indexFound] , qty_needed: event.target.value}
         parentsArray[indexFound] = parent 
        
       } else { parentsArray.push({parent_id: row.id,
                        parent_product: row.product,
                        qty_needed: event.target.value}) }

  setProductData({...productData, parents: parentsArray})
}
Nokwiw
  • 386
  • 4
  • 11
0

I saw the add function is work fine, you just need update existing_parent and update logic like this:

const existing_parent = productData.parents.find(tem => parent_id.parent_id === row.id);

if (existing_parent) {
  setProductData({
    ...productData,
    parents: productData.parents.map((parent) => {
      if (parent.id === row.id) {
        return {
          parent_id: row.id,
          parent_product: row.product,
          qty_needed: event.target.value,
        };
      }

      return {
        ...parent,
        qty_needed: event.target.value,
      };
    }),
  });
}
Viet
  • 12,133
  • 2
  • 15
  • 21