해당 포스팅은 react에서 datalist 태그를 사용해서 이메일 자동 완성 기능을 구현하는 방법에 대해 다룹니다.
SPOTV NOW 회원가입 페이지에 본 이메일 자동완성 기능이 인상 깊어서 진행중인 프로젝트에 적용해봤다.
구현 방법
- 자주 사용하는 이메일 리스트를 미리 정의한다.
- input value와 Email List 두 개를 useState로 등록한다.
- input에 onChange 이벤트를 등록한다.
- input value가 자주 쓰는 이메일 값과 합쳐져서 Email List 를 만든다.
- Email List를 순회하여태그의 value로 넣어준다.
- 선택한값을 input 값에 넣어준다.
<datalist>
란 무엇일까
<label for="email-choice">email:</label>
<input list="emailList" id="email-choice" name="email-choice" />
<datalist id="emailList">
<option value="test@gmail.com">
<option value="test@naver.com">
<option value="test@daum.net">
<option value="test@hanmail.net">
<option value="test@yahoo.com">
</datalist>
이메일 자동 왼성 로직을 구현하기 위해서는 <datalist>
라는 조금 생소한 태그를 사용한다. <option>
을 담는 태그로 <input>
에 타이핑을 하면 그 밑에 추천하는 옵션이 자동으로 나타낸다. 해당 옵션을 선택하면 <input>
의 값에 반영된다. 이 태그를 사용하기 위해서는 input의 list 속성값과 datalist의 id 속성값을 일치시켜야한다. 해당 태그를 사용하면 js로 적어야하는 코드가 획기적으로 줄어든다.
자주 사용하는 이메일 리스트 선언과 html 마크업
import React, { ChangeEvent, useState } from 'react';
const EmailInput = () => {
const frequencyEmails = [
'@naver.com',
'@gmail.com',
'@daum.net',
'@hanmail.net',
'@yahoo.com',
'@outlook.com',
'@nate.com',
'@kakao.com',
];
return (
<>
<label>이메일</label>
<input
list="emails"
placeholder="이메일을 입력하세요"
/>
<datalist id="emails">
</datalist>
<input type="submit">
</>
);
};
export default EmailInput;
자주 사용하는 이메일 string array을 미리 선언한다. 해당 array는 나중에 map 메서드를 사용해서 <option>
태그의 값으로 사용된다.
UseState로 상태관리 값 선언
import React, { ChangeEvent, useState } from 'react';
const EmailInput = () => {
const [emailValue, setEmailValue] = useState("");
const [emailList, setEmailList] = useState<string[]>([]);
const frequencyEmails = [
'@naver.com',
'@gmail.com',
'@daum.net',
'@hanmail.net',
'@yahoo.com',
'@outlook.com',
'@nate.com',
'@kakao.com',
];
const onChangeEmail = (e: ChangeEvent<HTMLInputElement>) => {
setEmailValue(e.target.value);
const userEmails = frequencyEmails.map((email) =>
e.target.value.includes('@')
? e.target.value.split('@')[0] + email
: e.target.value + email
);
setEmailList(userEmails);
};
return (
<>
<label>이메일</label>
<input
list="email"
value={emailValue}
placeholder="이메일을 입력하세요"
onChange={onChangeEmail}
/>
<datalist id="email">
{emailList &&
emailList.map((email, idx) => <option value={email} key={idx} />)}
</datalist>
<input type="submit">
</>
);
};
export default EmailInput;
useState로 상태 관리해줄 값은 두 가지다.
첫 번째로 input value를 입력받는 값, 두 번째는 (input value + 자주 사용하는 이메일) 조합의 string array다. 해당 값을 사용하는 로직은 input에 onChange 이벤트로 할당한다.
const onChangeEmail = (e: ChangeEvent<HTMLInputElement>) => {
setEmailValue(e.target.value);
const userEmails = frequencyEmails.map((email) =>
e.target.value.includes('@')
? e.target.value.split('@')[0] + email
: e.target.value + email
);
setEmailList(userEmails);
};
일단 현재 타이핑하는 값을 바로 email value로 반영한다. 이후에 자주 사용하는 이메일 도메인 값을 순회하면서 e.target.value에 이메일 도메인 값을 더 한다.
이 때 예외 패턴이 있다. 만약 유저가 option 값을 선택하지 않고 끝까지 타이핑 할 경우이다. 만약 예외 패턴을 생각하지 않고 코드를 적용시키면 도메인 두 개가 붙는 현상이 생긴다. 예를 들어 test@gmail.com
라고 유저가 적은 경우 test@gmail.com@gmail.com
라는 값이 option의 value에 할당되는 것이다.
이를 해결하기 위해 만약 e.target.value
에 ‘@’가 포함된 경우 e.target.value
를 @로 나눠서 앞에 있는 값만 가져온 후 다시 도메인과 연결한다. 이렇게 순회한 값을 setEmailList에 다시 할당한다.
<datalist id="email">
{emailList &&
emailList.map((email) => <option value={email} key={email} />)}
</datalist>
html으로 emailList가 존재하는 경우 map으로 순회하여 <option>
의 value로 할당한다.
결과물
완성~
'FrontEnd' 카테고리의 다른 글
[React🍇] TDD용 Eslint 설정하기 (0) | 2022.09.04 |
---|---|
[Js]innerHTML, innerText, textContent의 차이 (0) | 2022.09.02 |
[React🍇] axios interceptors typescript로 설정하기 (0) | 2022.08.29 |
[JS📜] 크롬확장프로그램 i18n 국제화 하는 방법 (0) | 2022.08.17 |
[라이브러리] Tailwind 장점과 다른 CSS 라이브러리와 차이점 (0) | 2022.08.16 |