Избавится от инициализации useEffect
У меня есть кастомный хук, задача которого показывать в input типа 'tel' флаг страны исходя из value input.
Такс же есть кастомный Input, который рендерит инпуты разных типов(tel/email/password и т.д) В компоненте Input, я взываю этот самый кстомный хук
const flag = useFlagCountrys(value)
value берет из props
Проблема в том что не важно какого типа инпут, при изменении value в инпуте, происходит иницализация flag. Нужно Добавить в хук проверку на тип инпута, а то на всех инпунтах, при каждом изменении value, у меня пересчитывается флаг.
Никак не пойму как это реализовать
Вот сам хук
export const useFlagCountrys = (value: string) => {
const [flag, setFlag] = useState("");
useEffect(() => {
const codeMap = new Map(array.map((item) => [item.code, item.flag]));
if (value.length <= 4) {
const flagData = codeMap.get(value);
if (flagData) {
setFlag(flagData);
}
} else {
for (let i = Math.min(value.length, 4); i >= 1; i--) {
const code = value.substring(0, i);
const flagData = codeMap.get(code);
if (flagData) {
setFlag(flagData);
break;
}
}
}
if (value.length === 0) {
setFlag("");
}
}, [value]);
return flag;
};
Вот компонент Input
export default function Input({error, extra, className, onChange, type, placeholder,
value = '', ...rest
}: InputProps) {
const flag = useFlagCountrys(value)
const [visible, setVisible] = useState(false)
const handleClick = () => onChange!("")
const handleChange = (e: ChangeEvent<HTMLInputElement>) => onChange!(e.target.value)
const handleVisible = () => setVisible(!visible)
switch (type) {
case 'tel':
return (
<Wrapper className={`input ${className || ""}`}>
{flag.length > 0 && (
<p>
<img width={17} src={flag} alt={flag}/> +
</p>
)}
<input
{...rest}
className="input_types"
type="tel"
value={value}
placeholder={placeholder}
onChange={handleChange}
/>
</Wrapper>
);
case 'text':
return (
<Wrapper className={`input ${className || ""}`}>
<input
{...rest}
className="input_types"
type="text"
value={value}
placeholder={placeholder}
onChange={handleChange}
/>
{extra && <div className="extra">{extra}</div>}
</Wrapper>
)
case 'search':
return (
<Wrapper className={`input ${className || ""}`}>
{type === 'search' && (
<div className="search_icon flex">
<SearchSvg/>
</div>
)}
<input
{...rest}
className="input_types"
type="search"
value={value}
placeholder={placeholder}
onChange={handleChange}
/>
{value?.length > 0 && (
<div className="clear_icon pointer" onClick={handleClick}>
<ClearInputSvg/>
</div>
)}
</Wrapper>
);
case 'password':
return (
<Wrapper className={`input ${className || ""}`}>
<input
{...rest}
className="input_types"
type={visible ? 'text' : 'password'}
value={value}
placeholder={placeholder}
onChange={handleChange}
/>
<button onClick={handleVisible} className="password_button" type="button">
<img
src={visible ? "/pic/icons/visible-hide.svg" : "/pic/icons/visible.svg"}
alt={visible ? "Hide visible" : "Visible"}
/>
</button>
</Wrapper>
);
default:
return null;
}
};