#javascript #reactjs
#javascript #reactjs
Вопрос:
Я попытался реализовать что-то вроде множественного выбора, где пользователь может либо выбрать значение из списка данных, либо ввести новое значение. Выбранное значение должно быть добавлено в массив, если пользователь нажимает enter. Для обнаружения изменений в поле ввода я использую onChange
и переменную состояния, которая сохраняет текущее введенное значение. Для обнаружения нажатия enter я использую onKeyDown
. Проблема в том, что я больше не могу вводить что-либо в поле ввода, однако выбор значений из списка данных работает. Я понял, что когда я комментирую onKeyDown
, я могу ввести что-то в поле ввода, а также могу выбирать из значений, предоставленных списком данных. Однако в этом случае добавление значений в массив при нажатии enter не работает. Я довольно новичок в React, есть ли что-то, что я пропустил? Мой текущий код выглядит следующим образом:
const EditableMultiSelect = ({ field, helpers, metadataField, editMode, setEditMode }) => {
const { t } = useTranslation();
const [inputValue, setInputValue] = useState('');
const handleChange = e => {
const itemValue = e.target.value;
setInputValue(itemValue);
}
const handleKeyDown = event => {
event.preventDefault();
if (event.keyCode === 13) {
field.value[field.value.length] = inputValue;
helpers.setValue(field.value);
setInputValue("");
}
}
const removeItem = () => {
console.log('to be implemented');
}
return (
editMode ? (
<>
<div
onBlur={() => setEditMode(false)}
ref={childRef}>
<input name="inputValue"
value={inputValue}
type="text"
onKeyDown={e => handleKeyDown(e)}
onChange={e => handleChange(e)}
placeholder={t('EDITABLE.MULTI.PLACEHOLDER')}
list="data-list"
/>
<datalist id="data-list">
{metadataField.collection.map((item, key) => (
<option key={key}>{t(item.value)}</option>
))}
</datalist>
</div>
{(field.value instanceof Array amp;amp; field.value.length !== 0) ? (field.value.map((item, key) => (
<span className="ng-multi-value"
key={key}>
{t(item)}
<a onClick={() => removeItem(key)}>
<i className="fa fa-times" />
</a>
</span>
))) : null}
</>
) : (
<div onClick={() => setEditMode(true)}>
{(field.value instanceof Array amp;amp; field.value.length !== 0) ? (
<ul>
{field.value.map((item, key) => (
<li key={key}>
<span>{item}</span>
</li>
))}
</ul>
) : (
<span className="editable preserve-newlines">
{""}
</span>
)}
<i className="edit fa fa-pencil-square"/>
</div>
)
);
};
Комментарии:
1. При обработке
handleKeyDown
, которую вы вызываетеevent.preventDefault();
, это эффективно предотвратит нажатие клавиши от каких-либо действий.
Ответ №1:
Вы вызываете event.preventDefault()
каждый раз при нажатии клавиши. Вы должны переместить его внутрь оператора if:
const handleKeyDown = event => {
if (event.keyCode === 13) {
event.preventDefault();
field.value[field.value.length] = inputValue;
helpers.setValue(field.value);
setInputValue("");
}
}
Ответ №2:
вы больше не можете ничего вводить во вводимый текст, потому что в обработчике события handleKeyDown вы вызываете event.preventDefault() в ранних строках. Поэтому я думаю, вам просто нужно переместить его в регистр if:
const handleKeyDown = event => {
if (event.keyCode === 13) {
event.preventDefault();
field.value[field.value.length] = inputValue;
helpers.setValue(field.value);
setInputValue("");
}
}