#javascript #arrays #reactjs #state
#javascript #массивы #reactjs #состояние
Вопрос:
Я пытаюсь обновить форму с двойным вводом, каждый раз, когда пользователи нажимают кнопку «Добавить» и изменяют состояние со своими значениями, и я хочу, чтобы эти 2 входа были «подключены» к нему. Было бы более понятно, если бы я графически показал, что я пытаюсь сделать:
[input] [second input] [remove button]
[input] [second input] [remove button]
[input] [second input] [remove button] ...
Намного проще, когда я пытаюсь динамически генерировать только один ввод, в настоящее время у меня даже нет полного кода, потому что я понятия не имею, как это сделать, но у меня есть некоторая часть, вот она:
состояние:
stuff: {
item: [],
quantity: []
},
и это был код для динамического добавления только одного поля ввода:
// i mapped stuff because before i only had one array and like this-> stuff: []
return this.state.stuff.map((element, index) =>
<div key={index}>
<input type="text" value={element||''} onChange={this.handleChange.bind(this, index)} />
<input type='button' value='remove' onClick={this.removeInput.bind(this, index)}/>
</div>
)
handleChange(index, event) {
let stuff = [...this.state.stuff];
stuff[index] = event.target.value;
this.setState({ stuff });
}
add(){
this.setState(previousState => ({ stuff: [...previousState.stuff,'']}))
}
removeInput(index){
let stuff = [...this.state.stuff];
stuff.splice(index,1);
this.setState({ stuff });
}
Честно говоря, я просто пробовал каждую идею, и в функции add () я не могу полностью понять, как добавление ''
в массив stuff заставляет код работать, если кто-нибудь объяснит это и даст мне решение для того, что я хочу сделать, я буду благодарен.
Ответ №1:
Я не могу полностью понять, как добавление «в
stuff
массив заставляет код работать
Если вы посмотрите на свой render()
метод, вы увидите, this.state.stuff.map(...)
таким образом, вы фактически сопоставляете каждое значение в stuff
массиве с соответствующим вводом. Поэтому, если вы добавляете другое значение в stuff
, компонент выполняет повторный запуск и сопоставляется новый ввод.
Теперь, чтобы добавить два ввода для каждой строки, вы могли бы сохранить два массива, но это затрудняет последующее управление данными. Вместо этого я бы использовал массив объектов, содержащий свойство item и quantity. Для этого внутри add()
метода добавьте новые объекты:
this.setState(({ stuff }) => ({ stuff: [...stuff, { item: "", quantity: 0 }));
Затем вам нужно изменить свое отображение внутри render()
, чтобы отобразить эти объекты:
this.state.stuff.map(({ item, quantity }, index) => (
<div>
Item: <input value={item} onChange={e => this.update(index, "item", e.target.value)} />
Quantity: <input value={quantity} onChange={e => this.update(index, "quantity", e.target.value)} />
</div>
));
Теперь единственное, что осталось, — это метод обновления, который принимает не только индекс, но и ключ для изменения:
update(index, key, value) {
this.setState(({ stuff }) => ({ stuff: stuff.map((it, i) => i === index ? { ...it, [key]: value }, it)) }));
}