[React|Refactor|TRACK1] Hashtags
TRACK1 리팩토링 이야기, Hashtags
Hashtags 기능 과정
- Hashtags가 생성되었을 때, style과 <div>를 생성한다.
- input창과 style을 지정한다.
- input에 onKeyDown을 통해 엔터시 발생하는 함수를 작성한다.
(?) onKeyDown이란?
-
event 매개변수를 통해 이벤트 객체에 접근
-
event.key를 통해 눌린 키의 값을 확인
-
event.keyCode를 사용하여 키보드 키의 코드 확인
- onKeyDown 함수 이름을 handleTag라고 하자.
- event.key를 통해 Enter가 아닌 경우, return 해준다. (함수를 빠져나온다.)
- input창에 들어오는 value값을 trim()하여 공백을 모두 제거해주었을 때, value이 없다면, 또 return해준다. (함수를 빠져나온다.)
- hashtag text를 담는 state 배열에 input 창에 들어오는 value를 담는데, 이전에 작성한 hashtagText들도 함께 담아 주는 것이 포인트이다.
` setHashtagText([…hashtagText, value]);`
- value를 ‘’ 빈 값으로 만들어주어 input의 값을 초기화 시켜준다.
- map 함수를 통해 hashtagText 배열을 화면에 띄워준다.
[ 전체 코드 ]
return (
const [hashtagText, setHashtagText] = useState<string[]>([]);
function handleEnterHashtag(e: KeyboardEvent<HTMLInputElement>) {
if (e.key !== "Enter") return;
const value = (e.target as HTMLInputElement).value;
if (!value.trim()) return;
setHashtagText([...hashtagText, value]);
(e.target as HTMLInputElement).value = "";
setHashtagLength(0); // 이건 아래 동적 width값 설정의 초기화를 위한 코드임.
}
{hashtagText.map((tag, index) => (
<Hashtag>
<CompleteHashtagWrapper>
<HashtagSharp># </HashtagSharp>
<CompletedHashtag>{tag}</CompletedHashtag>
</CompleteHashtagWrapper>
<DeleteHashtagIcon />
</Hashtag>
))}
);
<Hashtag>
<HashtagWrapper>
<HashtagSharp># </HashtagSharp>
<HashtagInput
placeholder="Hashtag"
onKeyDown={handleEnterHashtag} //onKeyDown로 함수 설정
// onChange={checkHashtagText}
inputWidth={hashtagLength}
/>
</HashtagWrapper>
</Hashtag>
Hashtags 동적으로 width값 설정해주기
- onChange(HTML 요소의 값이 변경될 때 발생하는 이벤트를 처리하는 핸들러 함수를 지정하는 속성(props))로 입력되는 text 확인
- text를 확인하는 함수 checkHashtagText는 input 값이 공백이 아니면, 한국어인지 한국어가 아닌지 살펴본 다음 길이를 설정
- style에 반영
[ 전체 코드 ]
const [hashtagLength, setHashtagLength] = useState<number>(0);
function checkHashtagText(e: React.ChangeEvent<HTMLInputElement>) {
const hashtagValue = e.target.value;
const koreanLength = hashtagValue.length * 1.5 + 1;
const nonKoreanLength = hashtagValue.length * 1.2 + 1;
hashtagValue.trim() !== ""
? checkKorean(hashtagValue)
? setHashtagLength(koreanLength)
: setHashtagLength(nonKoreanLength)
: setHashtagLength(0);
}
return(
<Hashtag>
<HashtagWrapper>
<HashtagSharp># </HashtagSharp>
<HashtagInput
placeholder="Hashtag"
onKeyDown={handleEnterHashtag}
onChange={checkHashtagText}
inputWidth={hashtagLength}
/>
</HashtagWrapper>
</Hashtag>
)
const HashtagInput = styled.input<{ inputWidth: number }>`
display: flex;
width: ${({ inputWidth }) => (inputWidth === 0 ? 9 : inputWidth)}rem;
${({ theme }) => theme.fonts.hashtag};
color: ${({ theme }) => theme.colors.gray1};
::placeholder {
color: ${({ theme }) => theme.colors.gray3};
}
`;
리팩토링 해야할 부분
- 중복 코드 제거 -> 함수 분리
function calculateHashtagLength(hashtagValue: string) {
const koreanLength = hashtagValue.length * 1.5 + 1;
const nonKoreanLength = hashtagValue.length * 1.2 + 1;
return checkKorean(hashtagValue) ? koreanLength : nonKoreanLength;
}
function checkHashtagText(e: React.ChangeEvent<HTMLInputElement>) {
const hashtagValue = e.target.value;
const hashtagLength = hashtagValue.trim() !== "" ? calculateHashtagLength(hashtagValue) : 0;
setHashtagLength(hashtagLength);
}