React — Input не работает при использовании onChange и onKeyDown

#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("");
  }
}