완성
숫자만 입력해도 자동으로 핸드폰 형식에 맞게 보여짐.

구현
mport React, { useState } from "react"; import styled from "styled-components"; const PhoneNum = () => { const [isCorrect, setIsCorrect] = useState(true); const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { const numStr = e.currentTarget.value.replaceAll(/[^\d]/g, "").slice(0, 11); e.currentTarget.value = numStr .split("") .map((char, i) => (i === 3 || i === 7 ? `-${char}` : char)) .join(""); setIsCorrect(/^\d{3}-\d{3,4}-\d{4}$|^$/.test(e.currentTarget.value)); }; return ( <Container> <h1>Phone Number</h1> <Input placeholder="Enter Phone Number" onChange={onChange} /> <ErrorMessage isCorrect={isCorrect}> 010-1234-5678 형식에 맞춰주세요! </ErrorMessage> </Container> ); }; export default PhoneNum; const Container = styled.div` display: flex; flex-direction: column; justify-content: center; align-items: center; `; const Input = styled.input` width: 332px; height: 32px; padding: 4px 6px; border-radius: 8px; border: 2px solid black; box-sizing: border-box; appearance: none; -webkit-appearance: none; margin: 0; `; const ErrorMessage = styled.p<{ isCorrect: boolean }>` color: red; display: ${({ isCorrect }) => (isCorrect ? "none" : "block")}; `;
과정
useState를 남발하지 말자
- useState는 새로 그리는 아주 비싼 연산임.
- 한 폼에서 useState를 3개 이상쓰면 숫자가 부드럽게 써지지 않음.
정규표현식에 대한 무지
test
는 정규식 패턴이 맞으면 true를, 아닐 경우 false를 반환함.
- +, ^$, or, []의 의미.
+
: 1개 이상. ex)n\d+ : “n” 뒤에 숫자가 1개 이상이다. “n1”, “n123″에 매치되지만 “n” 에는 매치되지 않는다.
^$
: 정규식 패턴의 시작과 끝을 알림.or
:|
문자를 이용하면 A 혹은 B에 매칭할 수 있음.[]
:^$
과 함께[]
내부에서 쓰이는 경우라면 뒤의 패턴에 일치하지 않는 것을 선택함. ex)ab[^0-9]: “ab” 뒤에 숫자가 아닌 것이 오는 것에만 매치한다. (“abc” – O, “ab1” – X)