#javascript #json #reactjs #react-hooks
#javascript #json #reactjs #реагирующие крючки
Вопрос:
Я работаю над формой, которая содержит раздел, в котором пользователи могут выбирать количество и категорию билета на концерт в выпадающем списке. Этот компонент создается динамически и может содержать больше элементов (количество категория). Выпадающие списки категорий связаны друг с другом. Поэтому, если вы выбираете одну категорию, значение других выпадающих списков должно быть установлено на то же выбранное значение. Но мне также нужно имя выпадающего списка каждой категории для проверки.
Вот как я создал объект категории:
const createCategory = () => {
let cat = {}
let nestedCat = {}
for (let it in item) {
for (let bt in item[it].buyertypes) {
cat2[item[it].buyertypes[bt].id] = ''
}
cat[item[it].id] = nestedCat
nestedCat = {}
}
return cat
}
const [category, setCategory] = useState(createCategory());
Это начальный объект:
{
9871: { 1: "", 2: "", 3: "" }
9872: { 5: "", 6: "", 8: "" }
}
Как я показываю и обрабатываю компонент ticket
const handleQuantity = e => {
setQuantity({
...quantity,
[e.target.name]: e.target.value
});
}
const handleCategory = e => {
setCategory({
...category,
[e.target.name]: e.target.value
});
}
const ShowData = () => {
let ticketIem = []
for (let it in item) {
for (let bt in item[it].buyertypes) {
let buyerType = item[it].buyertypes[bt]
ticketIem.push({
'price': buyerType.prices, 'catId': item[it].id,
'qntId': item[it].buyertypes[bt].id
})
}
}
return (
<div>
{ticketIem.map((i, index) => (
<div key={index} >
<div>
<label>Number</label>
<select
value={quantity[i.qntId]}
onChange={handleQuantity}
name={i.qntId}
>
<option value={0}>0</option>
<option value={1}>1</option>
</select>
</div>
<div>
<label>Category</label>
<select
value={category[i.catId]}
onChange={handleCategory}
name={i.catId}
>
<option value="">Choose</option>
{categories.map((cat, index) => (
<option key={index} value={cat.id} name={i.qntId}>
{cat.description} {cat.value}
</option>
))}
</select>
</div>
</div>
))}
</div>
)
}
После выбора опции в выпадающем списке объект категории будет установлен как:
{
9871: "11", 9872: "7"
}
но я ожидаю:
{
9871: { 1: "11", 2: "11", 3: "11" }
9872: { 5: "7", 6: "7", 8: "7" }
}
Ответ №1:
Если вы хотите установить все вложенные свойства определенной категории или количества, вам также потребуется выполнить итерацию ключей этих вложенных свойств. Используется Object.keys
для получения массива ключей вложенного объекта и преобразования их в новый объект с новым значением, установленным для каждого ключа.
Я предлагаю также использовать обновление функционального состояния, поскольку каждое обновление зависит от существующего / текущего состояния, поскольку оно неглубоко копируется в следующее состояние.
const handleQuantity = (e) => {
setQuantity((quantity) => ({
...quantity,
[e.target.name]: Object.keys(quantity[e.target.name]).reduce(
(obj, key) => ({
...obj,
[key]: e.target.value
}),
{}
)
}));
};
const handleCategory = (e) => {
setCategory((category) => ({
...category,
[e.target.name]: Object.keys(category[e.target.name]).reduce(
(obj, key) => ({
...obj,
[key]: e.target.value
}),
{}
)
}));
};
Комментарии:
1. Это работает отлично @DrewReese. Что, если я хочу установить для каждого вложенного свойства то, что пользователь выбирает в раскрывающемся списке?
2. @NimaPostanchi Разве это не то, что
target.value
значение? Или я не понимаю ваш последующий вопрос?3. @DrewResse в предыдущем случае я хотел присвоить всем вложенным свойствам определенной категории определенное значение, чтобы все выпадающие списки имели одинаковое значение, а предложенный вами код работал идеально. Теперь я хочу установить значение каждого выпадающего списка на то, что выбирает пользователь (не одинаковое значение для всех выпадающих списков). Теперь я хочу, чтобы объект выглядел как
{ 9871: { 1: "4", 2: "3", 3: "1" } 9872: { 5: "1", 6: "7", 8: "4" } }
target.value дает правильное значение, но я не могу установить для него правильное вложенное свойство. Надеюсь, я прояснил. Заранее спасибо за вашу помощь.4. @NimaPostanchi Я думаю, мне нужно немного больше контекста, так как сейчас я не вижу, какой пользовательский интерфейс относится к вложенным значениям. Он выглядит как
name={i.qntId}
иname={i.catId}
является ключами внешнего количества / категории (event.target.name
), а выбранным параметром является значение (event.target.value
), поэтому я не уверен, что вы используете для промежуточных ключей. Не могли бы вы предоставить работающий codesandbox, который я мог бы проверить?5. @DrewResse на самом деле этот вариант использования является расширением для предыдущего случая. Каждый раз, когда пользователь выбирает количество количества, будут показаны некоторые поля ввода для промо-кода на основе выбранного числа. Я создаю элементы этого промокода во вложенном объекте в обработчике события количества и присваиваю им имя ключа. Я не могу передать правильное имя ={} . здесь выполняется codesandbox , я хочу установить для объекта promotionCode каждого поля promotion значение e.taget.value в handleCode.