일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- vue 이벤트 수신
- vuex map
- SCSS forward
- vue mixin
- 프로그래머스 데브코스
- postcss
- nextjs사용법
- 고양이 사진 검색기
- 리액트
- flex
- Vue
- 다른컴퓨터에서 git사용
- vue 지역 컴포넌트
- 프로그래머스 프론트엔드 데브코스
- KDT 프로그래머스
- 프로그래머스 K_Digital Training
- SCSS use
- Spacer
- 쌓임맥락
- intersection opserver
- netlify redirect
- 폼 입력 바인딩
- SCSS import
- 이벤트 수식어
- SCSS extend
- 프로그래머스 데브코스 프론트엔드
- 리스트 렌더링
- react next
- KDT 프로그래머스 데브코스 프론트엔드
- git 같은계정 다른 컴퓨터
- Today
- Total
혼자 적어보는 노트
프로그래머스 데브코스 TIL - Day 54 본문
✅ 오늘의 학습
📌 React (7)
- 사용자 정의 Hook 연습하기
UseResize/ useLocalStorage / useForm / useTimeout / useInterval / useDebounce
Formik
이전의 useForm hook을 다시 복습하면서 Formik 이라는 form관련 라이브러리에 대해 알아보았다.
간단한 form을 구현할 때 사용하기 좋은 라이브러리이다.
import { useFormik } from 'formik';
한번 사용해보니 강의에서 구현한 useForm과 사용법이 거의 같았다.
하지만 강의에서 구현했을 땐 handlesubmit 이벤트를 발생시켜야 validate를 통한 유효성 검사를 했었는데,
formik의 경우에는 handlechange가 발생해도 바로 유효성 검사를 통해 error메세지를 반환한다는
차이점이 있었다.
그래서 formik에서는 Visited fields라는 것을 제공하는데
input을 선택했다가(focus) 다른 곳을 클릭했을 때(blur) 해당 에러 메세지가 반환될 수 있게
handleBlur와 touched 메서드을 제공한다.
const validate = ({ email, password }) => {
const errors = {};
if (!email) {
errors.email = '이메일을 입력해주세요.';
}
if (!password) {
errors.password = '비밀번호를 입력해주세요.';
}
if (!/^.+@.+\..+$/.test(email)) {
errors.email = '올바른 이메일을 입력해주세요.';
}
return errors;
};
export const Formik = (args) => {
const { values, errors, touched, handleSubmit, handleBlur, handleChange } =
useFormik({
initialValues: {
email: '',
password: '',
},
validate,
onSubmit: async (value) => {
await sleep();
alert(JSON.stringify(value));
},
});
return (
<form onSubmit={handleSubmit}>
<div>
<input
name="email"
type="email"
value={values.email}
onBlur={handleBlur}
onChange={handleChange}
/>
{touched.email && errors.email}
</div>
<div>
<input
name="password"
type="password"
value={values.password}
onBlur={handleBlur}
onChange={handleChange}
/>
{touched.password && errors.password}
</div>
<button type="submit">Submit</button>
</form>
);
};
useTimeout
지정한 시간이 지나면 함수를 실행시키는 hook
함수를 통해 타이머를 시작하는것과 페이지에 진입하자마자 시작되는 것. 총 2가지를 구현했다.
[useTimeoutFn.js]
import { useCallback, useEffect, useRef } from 'react';
const useTimeoutFn = (fn, ms) => {
const timeoutId = useRef();
const callback = useRef(fn);
useEffect(() => {
callback.current = fn;
}, [fn]);
const run = useCallback(() => {
timeoutId.current && clearTimeout(timeoutId.current);
timeoutId.current = setTimeout(() => {
callback.current();
}, ms);
}, [ms]);
const clear = useCallback(() => {
timeoutId.current && clearTimeout(timeoutId.current);
}, []);
useEffect(() => clear, [clear]);
return [run, clear];
};
export default useTimeoutFn;
debounce와 비슷한 형태로 중복으로 호출이 일어날 경우
기존에 있던 timeout을 삭제하고 새롭게 만들어주었다.
* 페이지 이동을 했을 때 timeout이 남아서 실행되는 버그가 생길 수 있기 때문에
hook이 사라지면 꼭 clear를 해주어야 한다.
useTimeoutFn이 완성되면 해당 hook을 활용하여 페이지 접근 시 바로 실행되는 hook을 추가로 만들 수 있다,
[useTimeout.js]
import { useEffect } from 'react';
import useTimeoutFn from './useTimeoutFn';
const useTimeout = (fn, ms) => {
const [run, clear] = useTimeoutFn(fn, ms);
useEffect(() => {
run();
return clear;
}, [run, clear]);
return clear;
};
export default useTimeout;
useIntervalFn과 useInterval도 위와 같은 형태로 만들면 된다.
useDebounce
useDebounce도 useTimeoutFn을 사용하여 간단하게 구현할 수 있다.
import { useEffect } from 'react';
import useTimeout from './useTimeout';
const useDebounce = (fn, ms, deps) => {
const [run, clear] = useTimeout(fn, ms);
// eslint-disable-next-line
useEffect(run, deps);
return [run, clear];
};
export default useDebounce;
3번째 인자로 dependency(바뀌어서 들어오는 Value 값)를 받아서 useEffect에 넣어줌으로써
특정 초 이내에 deps값이 변경될 때마다 기존의 setTimeout을 종료시키고 다시 실행시킬 수 있다.
✍ 느낀 점
예전에 hook을 사용해서 Debounce를 구현했다가 잘 안되었던 기억이 있는데
지금 생각해보니 그땐 useCallback과 useRef를 사용하지 않아서 매번 새로운 함수를 만들고
새로운 timer가 생성되어서 잘 안되었던 것 같다. 그것 외에도 이상하게 코드를 짠 것들이 떠올랐다..
그간 리액트의 이론적인 부분들을 공부하기도 하고 이번에 여러 강의들을 듣고나니
이전에 만들었던 프로젝트를 열어보기가 두려워졌다.. 거의 새로 만드는 수준으로 리팩토링 해야 할 듯🤣
'스터디' 카테고리의 다른 글
프로그래머스 데브코스 TIL - Day 56 (0) | 2022.06.05 |
---|---|
프로그래머스 데브코스 TIL - Day 55 (0) | 2022.06.03 |
프로그래머스 데브코스 TIL - Day 53 (0) | 2022.06.02 |
프로그래머스 데브코스 TIL - Day 51 (0) | 2022.05.30 |
프로그래머스 데브코스 TIL - Day 50 (0) | 2022.05.27 |