이전 포스팅은 회원가입 페이지 만들기에 대해 포스팅하였다.
2022.10.24 - [개발 공부 시리즈/Slack클론코딩] - [인프런 강의] zerocho Slack 클론 코딩 (8) - 회원가입 페이지 만들기
이번 포스팅에서는 커스텀 훅을 만들어보겠다.
※ 이 포스팅은 zerocho님의 slack 클론 코딩 강좌를 따라 하면서 정리해놓은 포스팅입니다.
1. 중복 코드 제거하기
alecture/pages/SignUp/index.tsx
const SignUp = () => {
const [email, setEmail] = useState('');
const [nickname, setNickName] = useState('');
const [password, setPassword] = useState('');
const [passwordCheck, setPasswordCheck] = useState('');
//비밀번호 , 비밀번호확인 같은지 여부 판단
const [mismatchError, setMissmatchError] = useState(false);
const onChangeEmail = useCallback((e) => {
setEmail(e.target.value);
},[]);
const onChangeNickname = useCallback((e) => {
setNickName(e.target.value);
},[]);
//비밀번호 변경 함수
const onChangePassword = useCallback((e) => {
setPassword(e.target.value);
setMissmatchError(e.target.value !== passwordCheck)
},[passwordCheck]);
//비밀번호 확인 변경 함수
const onChangePasswordCheck = useCallback((e) => {
setPasswordCheck(e.target.value);
setMissmatchError(e.target.value !== password)
},[password]);
//......
이전 포스팅에서 만들었던 회원가입 페이지이다.
이 페이지의 코드 중 email과 nickName, onChangeEmail, onChangeNickname 같은 코드를 두 번 사용하는 형태가 되는데 커스텀 훅을 사용해 중복을 제거할 수 있다.
2. CUSTOM HOOK 만들기
hooks 폴더에 useInput.ts 파일을 생성한다.
useInput.ts
//useInput.ts
import { Dispatch, SetStateAction, useCallback, useState} from "react"
type ReturnTypes<T = any> = [T, (e: any) => void, Dispatch<SetStateAction<T>>]
const useInput = <T = any> (initialData: T) : ReturnTypes<T> => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e) => {
setValue(e.target.value);
}, [])
return [ value, handler, setValue];
}
export default useInput;
useInput.ts는 Input에 대한 커스텀 훅을 만든 예제이다.
SignUp/index.tsx 에 다음과 같은 코드들을 추가한다.
index.tsx
import React, {useCallback, useState} from "react";
import { Header, Form, Label, Input, Button, LinkContainer, Error } from './styles';
import { Link } from 'react-router-dom';
//커스텀 훅 추가
import useInput from '@hooks/useInput';
const SignUp = () => {
//단순한 input 중복일때 useInput 사용
const [email, onChangeEmail] = useInput('');
const [nickname,onChangeNickname] = useInput('');
//useInput을 사용했을때 커스터 마이징이 필요할 때 가운데를 빈 값으로 두면된다.
const [password, ,setPassword] = useInput('');
const [passwordCheck, ,setPasswordCheck] = useInput('');
//비밀번호 , 비밀번호확인 같은지 여부 판단
const [mismatchError, setMissmatchError] = useState(false);
//비밀번호 변경 함수
const onChangePassword = useCallback((e) => {
setPassword(e.target.value);
setMissmatchError(e.target.value !== passwordCheck)
},[passwordCheck]);
//비밀번호 확인 변경 함수
const onChangePasswordCheck = useCallback((e) => {
setPasswordCheck(e.target.value);
setMissmatchError(e.target.value !== password)
},[password]);
email과 nickname의 setEmail, setNickname을 useInput 의 setValue를 사용하여 중복을 제거하였다.
onChangeEmail, onChangeNickname 함수도 useInput의 handler 부분으로 보내지게 되어 마찬가지로 중복을 제거시켰다.
onChangePassword와 onChangePasswordCheck 함수는 중복되는 코드도 있지만 중복되지 않는 코드들도 있다.
그렇기 때문에 가운데에 빈 값으로 두면 커스터마이징이 필요한 코드를 커스텀 훅과 같이 사용할 수 있다.
3. CUSTOM HOOK 코드 살펴보기
import { Dispatch, SetStateAction, useCallback, useState} from "react"
//매개변수는 타입을 꼭 붙여줘야한다.
//리턴 등은 타입을 타입스크립트가 추론해 주어서 명시하지 않아도 되지만
//매개변수는 타입을 명시해줘야함
//어떤 타입이 들어올지 모를땐 any
// : 이후에는 리턴 타입을 설정해준다.
// Dispatch 와 SetStateAction은 React가 제공하는 타입이다.
//리턴타입을 변수로 설정 할 수 있다.
//리턴 타입에 any를 안 넣을 려면 any 대신 ChangeEvent<HTMLInputElement>
//e.target.value 대신 e.target.value as unkown as T를 넣으면 해결 된다.
type ReturnTypes<T = any> = [T, (e: any) => void, Dispatch<SetStateAction<T>>]
const useInput = <T = any> (initialData: T) : ReturnTypes<T> => {
console.log(initialData);
const [value, setValue] = useState(initialData);
const handler = useCallback((e) => {
setValue(e.target.value);
}, [])
return [ value, handler, setValue];
}
export default useInput;
타입 스크립트를 사용해 useInput이라는 커스텀 훅을 만들었다.
input의 onChange 함수의 작동이 일어나게 되면, 값을 바꾸어주는 커스텀 훅이다.
타입 스크립트는 리턴 타입은 타입이 자동적으로 판단할 수 있지만 매개변수는 타입을 꼭 명시해 주어야 한다.
useInput의 타입은 <T>라는 제네릭 타입으로 받게된다.
제네릭으로 선언하고 <T : any > 라는 말은 어떤 타입이 들어올지 모른다는 말이다.
(intialData : T )는 받는 매개변수고 이전에 제네릭으로 any라고 설정해 준 값이 들어오게 되며
: 뒤쪽은 리턴할 타입을 명시한다.
위처럼 type으로 선언하여 사용할 수도 있다.
dispatch 함수는 react에서 제공하는 함수이고 , dispatch()를 사용하면 HTML 안에서 reducer함수를 동작시킬 수 있다.
SetStateAction 타입은 S(initial state)라는 제너릭을 가지고 있고, S 타입의 Parameter(prevState)를 입력받아 S타입의 값을 리턴하는 함수이다.
두 가지를 제네릭 타입으로 같이 사용하게 된다.
위 코드를 다음과 같이 ChangeEvent <HTMLInputElement>와 e.target.value as unknown as T로 변경하여 사용할 수 있다.
import { Dispatch, SetStateAction, useCallback, useState, ChangeEvent } from 'react';
//변경
type ReturnTypes<T> = [T, (e: ChangeEvent<HTMLInputElement>) => void, Dispatch<SetStateAction<T>>];
const useInput = <T>(initialData: T): ReturnTypes<T> => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e: ChangeEvent<HTMLInputElement>) => {
//변경
setValue((e.target.value as unknown) as T);
}, []);
return [value, handler, setValue];
};
export default useInput;
ChangeEvent <HTMLInputElement>는 Input태그의 이벤트가 일어날 때 이벤트의 타입을 찾을 수 있다.
만약 textarea 태그이면 <HTMLTextAreaElement>로 바꾸어주면 된다.
다음과 같이 입력을 하고 submit을 눌러도 customHook의 onChange 이벤트가 값을 제대로 전달하는 것을 볼 수 있다.
'개발 공부 시리즈 > Slack클론코딩' 카테고리의 다른 글
[인프런 강의] zerocho Slack 클론 코딩 (11) - 로그인 페이지 만들기 (0) | 2022.12.09 |
---|---|
[인프런 강의] zerocho Slack 클론 코딩 (10) - axios로 요청보내기 CORS, proxy (0) | 2022.11.06 |
[인프런 강의] zerocho Slack 클론 코딩 (8) - 회원가입 페이지 만들기 (2) | 2022.10.24 |
[인프런 강의] zerocho Slack 클론 코딩 (7) - 코드 스플리팅과 이모션 (0) | 2022.10.20 |
[인프런 강의] zerocho Slack 클론 코딩 (6) - 폴더 구조와 리액트 라우터 (0) | 2022.10.19 |
댓글