Создайте массив объектов из управляемых входных данных

#javascript #arrays #reactjs #ecmascript-6 #spread

Вопрос:

У меня есть форма с динамически создаваемыми входными данными. Количество входных данных и их название меняются в зависимости от полученных данных. Я хотел бы создать массив объектов из значений, которые я получаю из этих входных данных.

 const [form, setForm] = useState([]);
packages = ["250g", "500g"] //This varies depending on fetched data
 

HTML:

 <form onSubmit={(e) => handleSubmit(e)}>
            <ul>
                {packages.map((packageName, index) => {
                    return (
                        <li key={index}>
                            <p>{packageName}</p>
                            <input type="number" min={0} value={form[packageName]} onChange={(e) => handleChange(e, packageName)} />
                            <button type="submit">BUY</button>
                        </li>
                    );
                })}
            </ul>
        </form>
 

Функция переключения передач:

 const handleChange = (e, packageName) => {
    setForm([...form, { [packageName]: parseInt(e.target.value) }]);
};
 

Выходной ток:

 form: [
    {
       "250g": 1
    },
    {
       "250g": 2
    },
    {
       "250g": 3
    },
    {
       "500g": 1
    },
    {
       "500g": 2
    }

]
 

Каждое изменение входного значения создает новый объект, но я бы хотел просто изменить значение в этом конкретном объекте, которое изменяется в данный момент.

Желаемый результат:

 form: {
    "250g": { quantity: 3 },
    "500g": { quantity: 2 }
}
 

Комментарии:

1. Ваш желаемый вывод не является допустимой структурой JS. Было бы нормально, если form бы это был объект, а не массив.

2. я предполагаю, что структура такова? form: [ { "250g": { quantity: 3 }}, { "500g": { quantity: 2 }} ]

3. хорошо, теперь я увидел из редактирования, каков желаемый результат

4. @MadGrip проверь мой ответ. я отредактировал его, потому что думал, что форма-это массив, но я видел правки 🙂

5. МэдЖрип, ты проверил наши ответы?

Ответ №1:

Вы можете использовать объект вместо массива.

 const [form, setForm] = useState({});

const handleChange = (e, packageName) => {
    setForm({
         ...form,
         [packageName]: { quantity: parseInt(e.target.value) }
    });
}
 

Ответ №2:

Я вставляю образец исполняемого файла vanilla js.

    let form = {}

function add(str) {
 if (form[str]) {
  form[str].quantity  = 1
 } else {
  form[str] = { quantity: 1}
 }
}

add("250g")
add("250g")
add("250g")
add("750g")
add("500g")
add("750g")

console.log(form) 

Так что, я думаю, ваш метод станет таким

 const handleChange = (e, packageName) => {
  let newForm = JSON.parse(JSON.stringify(form))
  
     if (newForm[packageName]) {
      newForm[packageName].quantity  = parseInt(e.target.value)
       setForm(newForm);
     } else {
            setForm({
         ...form,
         [packageName]: { quantity: parseInt(e.target.value) }
     }  
}