blog
wanted
pre-on-boarding
원티드 프리온보딩 과제 - 3일차
useInput
import { ChangeEvent, useState } from 'react';
function useInput<T>(inputGroup: T) {
const [inputValues, setInputValues] = useState(inputGroup);
const handleInputChange = (field: keyof T) => {
return (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setInputValues((prev) => ({
...prev,
[field]: e.target.value,
}));
};
};
const resetAllInput = () => {
const resetObject: { [key: string]: string } = {};
setInputValues((prev) => {
if (prev) {
Object.keys(prev).forEach((item) => {
resetObject[item] = '';
});
}
return prev;
});
};
const resetSpecificInput = (field: keyof T) => {
setInputValues((prev) => ({
...prev,
[field]: '',
}));
};
return { handleInputChange, inputValues, resetAllInput, resetSpecificInput };
}
export default useInput;
학원에서 포폴 만들 때 사용했던 custom hook을 개선했습니다.
import axios from 'axios';
import { useRef, useState } from 'react';
import { client } from '../api/client';
import { CustomButton, CustomInput } from '../components';
import { baseURL } from '../constants/constant';
import { useInput } from '../hooks';
import { checkEmail, checkPassword } from '../utils';
function Signup() {
const { inputValues, handleInputChange } = useInput<{
id: string;
pw: string;
}>({ id: '', pw: '' });
const idRef = useRef<HTMLInputElement>(null);
return (
<main className="flex h-screen flex-col items-center justify-center gap-4">
<div className="flex flex-col gap-4">
<CustomInput
value={inputValues.id}
placeholder="user@user.com"
onChange={handleInputChange('id')}
inputLabel={{ label: '아이디', id: '아이디' }}
errorMessage={idFeedback || checkEmail(inputValues.id)}
testId="email-input"
type="email"
customRef={idRef}
/>
<CustomInput
value={inputValues.pw}
placeholder="8자리 이상 입력해주십시오."
onChange={handleInputChange('pw')}
inputLabel={{ label: '비밀번호', id: '비밀번호' }}
errorMessage={checkPassword(inputValues.pw)}
testId="password-input"
type="password"
/>
</div>
</main>
);
}
export default Signup;
- 이전과 다르게 typesafe하게 사용할 수 있게 되었습니다.
다시 자동완성 뽕맛에 취할 수 있습니다. - 여전히 아쉽습니다. 대입하는 인자로 알아서 타입 추론이 되게 만들고 싶었습니다.
{id: "", pw: ""}
만 대입해도inputValues
에 알아서inputValues.id
,inputValues.pw
로 접근가능하게 작성하고 싶습니다. 호출하는 사람이 제네릭을 지정해야 한다는 점이 치명적인 단점입니다. - 지금도 타입스크립트 기초가 너무 안 되어 있습니다.
조건부 타입
input에 의존성 props를 만들고 싶었습니다. 일단 못찾았습니다.
<CustomInput value="adsf" onChange={(e) => {}} />
<CustomInput value="adsf" onChange={(e) => {}} label="label" id="id" />
원래는 이렇게 label을 지정 id도 같이 입력하게 만들고 싶었습니다.
이거에 오늘 3 ~ 4시간을 들였습니다.
<CustomInput value="adsf" onChange={(e) => {}} inputLabel={{ label: "비밀번호", id: "비밀번호" }} />
<CustomInput value="adsf" onChange={(e) => {}} />
그냥 이렇게 해결할 수 있었습니다.
@example
/**
* @example
* <CustomInput value="adsf" onChange={(e) => {}} />
* <CustomInput value="adsf" onChange={(e) => {}} inputLabel={{ label: "label", id: "id" }} />
*/
함수 hover
하면 JSX 예시를 볼 수 있었습니다.