0

I want add object inside of array items

I am trying to manage objects inside of an array with useState but is not working i have only in object but I want the object in interior of the array of items. When I click add items on the button i want add the element and if possible remove this element when i click remove items in button link with inputs (see the image)

Like :

company:"Apple",
companyAdress:"5 avenue triagle",
items: [
        {
          itemName: Computer,
          itemQuantity: 20,
          itemPrice: 209
        },

       {
          itemName: Computer,
          itemQuantity: 20,
          itemPrice: 209
        },
]

My code :

 const [info, setInfo] = useState({});

const [itemForm, setItemForm] = useState({ num: 1 })

const handleRemoveItem = (e) => {
        e.preventDefault();
        setItemForm((itemForm) => ({ num: itemForm.num - 1 }))
    }



 const handleAddItem = (e) => {
        e.preventDefault();
        setItemForm((itemForm) => ({ num: itemForm.num + 1 }))
    }




 <label>Company</label>
 <input onChange={(e) => { setInfo({ ...info, company: e.currentTarget.value}); }} placeholder="Company"></input>
 <label>company Adress</label>
 <input onChange={(e) => { setInfo({ ...info, companyAdress: e.currentTarget.value }); }} placeholder="Adresse"></input>
               

 <ul className="space-y-3">
 {[...Array(itemForm.num)].map((x, i) => {
         return (
          <li key={i}>
           <div>
<input  onChange={(e) => { setInfo({...info,itemName: e.currentTarget.value  });}} name="itemName" placeholder="itemName:" ></input>
       <input  onChange={(e) => { setInfo({ ...info, itemQuantity: e.currentTarget.value }); }} type="number" name="itemQuantity" placeholder="Quantity:"></input>
                                        <input onChange={(e) => { setInfo({ ...info, itemPrice: e.currentTarget.value }); }} type="number" name="itemPrice" placeholder="Price:"></input>

               <button onClick={handleRemoveItem}>Enlever </button>
               <button onClick={handleAddItem}>+ Add New Item</button>
                                    </div>
                                </li>
                            )
                        }
                        )}
                    </ul>

1 Answer 1

1

i do something like this using an id to find the iteminfo.

i am currying the itemid here but you could put the itemId as part of the input id and find it that way if you like - then you could use one function. anyway hope it helps

also i am just using the id as the key for the object you might what to be more strict on this ¯_(ツ)_/¯

i would also put the factory and defaultInfo else where in your app

import { useState } from "react";
import { v4 as uuidv4 } from "uuid";
const defaultItemFactory = () => {
  return { itemName: "", itemQuantity: "", itemPrice: "", id: uuidv4() };
};
const defaultInfo = {
  company: "",
  companyAdress: "",
  items: [defaultItemFactory()],
};

function App() {
  const [info, setInfo] = useState(defaultInfo);

  const changeHanlder = (event) => {
    const { id, value } = event.currentTarget;
    setInfo((_info) => {
      return { ..._info, [id]: value };
    });
  };

  const itemHanlder = (itemId) => (event) => {
    const { id, value } = event.currentTarget;
    setInfo((_info) => {
      if (id === "add")
        return { ..._info, items: _info.items.concat(defaultItemFactory()) };
      const items = _info.items
        .map((item) => {
          if (item.id !== itemId) return item;
          if (id === "remove") return null;
          return { ...item, [id]: value };
        })
        .filter((out) => out);
      return { ..._info, items };
    });
  };

  return (
    <div className="App">
      <label>Company</label>
      <input
        id={"company"}
        value={info.company}
        onChange={changeHanlder}
        placeholder="Company"
      ></input>
      <label>company Adress</label>
      <input
        id={"companyAdress"}
        value={info.companyAdress}
        onChange={changeHanlder}
        placeholder="Adresse"
      ></input>

      <ul className="space-y-3">
        {info.items &&
          info.items.map((item, i) => {
            return (
              <li key={`item-${item.id}`}>
                <div>
                  <input
                    id={"itemName"}
                    value={item.itemName}
                    onChange={itemHanlder(item.id)}
                    name="itemName"
                    placeholder="itemName:"
                  ></input>
                  <input
                    id={"itemQuantity"}
                    value={item.itemQuantity}
                    onChange={itemHanlder(item.id)}
                    type="number"
                    name="itemQuantity"
                    placeholder="Quantity:"
                  ></input>
                  <input
                    id={"itemPrice"}
                    value={item.itemPrice}
                    onChange={itemHanlder(item.id)}
                    type="number"
                    name="itemPrice"
                    placeholder="Price:"
                  ></input>

                  <button id={"remove"} onClick={itemHanlder(item.id)}>
                    Enlever{" "}
                  </button>
                  <button id={"add"} onClick={itemHanlder(item.id)}>
                    + Add New Item
                  </button>
                </div>
              </li>
            );
          })}
      </ul>
    </div>
  );
}

export default App;

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.