sla
sla

Reputation: 21

Add object inside of array react input value

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>

Upvotes: 0

Views: 440

Answers (1)

strimbob
strimbob

Reputation: 11

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;

Upvotes: 1

Related Questions