프로젝트
Input 컴포넌트
나는시화
2023. 12. 5. 16:44
.inputbox{
display: flex;
flex-direction: column;
gap: 5px;
}
.inputbox-laber{
color:rgba(0, 0, 0, 0.7);
font-size: 14px;
font-weight: 400;
line-height: 140%;
}
.inputbox-container{
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
padding: 11px 16px 11px 0px;
display: flex;
align-items: center;
}
.inputbox-container-error{
border-bottom: 1px solid rgba(255, 0, 0, 0.7);
padding: 11px 16px 11px 0px;
background-color: rgba(250, 250, 250, 1);
display: flex;
align-items: center;
}
.input{
border: none;
background: none;
outline: none;
flex:1;
color: rgba(0, 0, 0, 0.7);
font-size: 14px;
font-weight: 400;
line-height: 140%;
}
.inputbox-message{
color: rgba(255, 0, 0, 0.7);
font-size: 10px;
font-weight: 400;
line-height: 140%;
}
import React, { ChangeEvent,KeyboardEvent, forwardRef } from 'react';
import './style.css';
// interface: Input Box 컴포넌트 Properties
interface Props{
label: string;
type: 'text' | 'password';
placeholder: string;
value: string;
setValue: React.Dispatch<React.SetStateAction<string>>;
error: boolean;
icon?: string ;
onButtonClick?: ()=>void;
message?: string;
onKeyDown?:(event:KeyboardEvent<HTMLInputElement>)=>void;
}
// component: Input Box 컴포넌트
const InputBox = forwardRef<HTMLInputElement, Props>((props: Props, ref) =>{
// state: properties
const {label,type,error,placeholder,value,icon,message} = props;
const {setValue,onButtonClick,onKeyDown} = props;
// event handler : input 값 변경 이벤트 처리 함수
const onChangeHandler = (event: ChangeEvent<HTMLInputElement>) =>{
const {value} = event.target;
setValue(value);
}
// event handler : input 키 이벤트 처리 함수
const onKeyDownHandler = (event: KeyboardEvent<HTMLInputElement>) =>{
if(!onKeyDown) return;
onKeyDown(event);
}
// render: Input Box 컴포넌트
return (
<div className='inputbox'>
<div className='inputbox-label'>{label}</div>
<div className={error ? 'inputbox-container-error' : 'inputbox-container'}>
<input ref={ref} type={type} className='input' placeholder={placeholder} value={value} onChange={onChangeHandler} onKeyDown={onKeyDownHandler}/>
{onButtonClick !== undefined &&
<div className='icon-button'>
{icon !== undefined && <div className={`icon ${icon}`}></div>}
</div>
}
<div className='icon-button'>
<div className='icon eye-light-off-icon'></div>
</div>
</div>
{message!==undefined &&<div className='inputbox-message'>{message}</div>}
</div>
);
});
export default InputBox;
어려웠던 점 : Ref, forwordRef(부모->자식 html element )
강의를 들으면서 내가 이전에 했던 프로젝트는 매우 부족하다는 걸 다시 한번 느꼈다.
무엇을 만들고 싶은지, 어떤 기능들이 필요한지 등 계획을 제대로 세우고 해야지 나중에 코드 중복, 코드 수정 등 불필요한 행동들을 줄일 수가 있을 거 같다.
타입 스크립트를 처음 사용해보는데 문법을 완전히 익히고 사용하는 것이 아니라 모르는 것들이 많은데, 이 부분들을 따로 공부하는 시간이 많이 들고 있다.
재밌다..