Answer the question
In order to leave comments, you need to log in
How to correctly add ref to custom input?
Hello! There were problems creating a link to a custom input.
In particular, custom input does not have a ref property.
Code with comment below:
import React, { ReactElement } from 'react';
import classNames from 'classnames';
import './index.scss';
import Input from '../Input';
interface IAutocompleteInputProps {
readonly placeholder: string | undefined;
readonly data: string[];
readonly addDataHandler: (newData: string) => void;
}
const AutocompleteInput: React.FC<IAutocompleteInputProps> = (props) => {
const { placeholder, data, addDataHandler } = props;
const inputRef = React.useRef<HTMLInputElement>(null);
const [inputValue, setInputValue] = React.useState<string>('');
const [filtredValues, setFiltredValues] = React.useState<string[]>([]);
const [currentFiltredValue, setCurrentFiltredValue] = React.useState<string>('');
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
const newValue = event.target.value.toLowerCase();
const foundedValues = data.filter(el => el.slice(0, newValue.length).includes(newValue)); //TODO: need a better way to find
const lastValues = data.filter(el => el.includes(newValue) && !foundedValues.includes(el)); // matched values
foundedValues.push(...lastValues);
setFiltredValues(foundedValues);
setCurrentFiltredValue('');
}
const handleKeyPress = (event: React.KeyboardEvent) => {
if(event.key === 'Enter' && inputValue) {
event.preventDefault();
if(currentFiltredValue) {
setInputValue(currentFiltredValue);
setCurrentFiltredValue('');
setFiltredValues([]);
} else {
addDataHandler(inputValue.toLocaleLowerCase());
setInputValue('');
}
} else if (event.keyCode === 40 && filtredValues) {
filtredValues.indexOf(currentFiltredValue) + 1 === filtredValues.length
? setCurrentFiltredValue(filtredValues[0])
: setCurrentFiltredValue(filtredValues[filtredValues.indexOf(currentFiltredValue) + 1])
} else if (event.keyCode === 38 && filtredValues) {
filtredValues.indexOf(currentFiltredValue) === 0
? setCurrentFiltredValue(filtredValues[filtredValues.length - 1])
: setCurrentFiltredValue(filtredValues[filtredValues.indexOf(currentFiltredValue) - 1])
}
}
const handleMouseClick = (event: React.MouseEvent<HTMLDivElement>) => {
console.log((event.target as Element).id)
const choosenFiltredValue = (event.target as Element).id;
setInputValue(choosenFiltredValue);
setFiltredValues([]);
setCurrentFiltredValue('');
}
return (
<div className="autocomplete-input">
<Input
type='text'
autoComplete='off'
placeholder={placeholder}
value={inputValue}
onChange={handleInputChange}
onKeyDown={handleKeyPress}
autoFocus={true}
//ref={inputRef} не имеет свойства ref
/>
<div className="item-container">
{(filtredValues.length && inputValue) ?
filtredValues.map(filtredValue =>
<div
key={filtredValue}
className={classNames('item-container__item',{
'item-container__item--selected': filtredValue === currentFiltredValue
})}
onClick={handleMouseClick}
id={filtredValue}
>
{filtredValue}
</div>
)
: undefined
}
</div>
</div>
)
}
export default AutocompleteInput;
import React, { InputHTMLAttributes } from 'react';
import './index.scss';
const Input: React.FC<InputHTMLAttributes<HTMLInputElement>> = (props) => {
return (
<input className="input" {...props}/> //имеет свойство ref
)
}
export default Input;
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question