Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- KDT 프로그래머스
- SCSS use
- flex
- vuex map
- KDT 프로그래머스 데브코스 프론트엔드
- SCSS extend
- netlify redirect
- vue 이벤트 수신
- Vue
- postcss
- 프로그래머스 데브코스
- 이벤트 수식어
- SCSS forward
- 프로그래머스 K_Digital Training
- Spacer
- git 같은계정 다른 컴퓨터
- 다른컴퓨터에서 git사용
- 프로그래머스 데브코스 프론트엔드
- SCSS import
- react next
- 쌓임맥락
- vue 지역 컴포넌트
- 리스트 렌더링
- 고양이 사진 검색기
- 프로그래머스 프론트엔드 데브코스
- nextjs사용법
- vue mixin
- 폼 입력 바인딩
- 리액트
- intersection opserver
Archives
- Today
- Total
혼자 적어보는 노트
[React] 리액트에서 디바운싱 구현하기 본문
이전에 Vanilla Javascript로 디바운싱을 구현해본 적 있었는데
이전에 만들고 있던 React 사이드 프로젝트인 todoList를 리팩토링 하면서 적용해보면 좋을 것 같아서
디바운싱을 간단하게 구현해보려고 한다.
debounce
연속으로 호출되는 함수들 중 마지막 함수(or 처음 호출된 함수)만 호출하도록 하는 것
todoList의 step값이 onChange될 경우
변경한 값이 바로 데이터베이스에 저장되기를 원하는 상황이다.
현재 데이터베이스는 firebase의 realtime base를 사용하고 있었고
value가 변경될 때마다 데이터통신을 하는 것이 부담이 된다고 생각이 들었다.
[코드의 일부]
import React, { useCallback, useState } from "react";
import CheckBtn from "./Button/CheckBtn";
import CloseBtn from "./Button/CloseBtn";
import { deleteStep } from "../modules/todo";
import { onRemoveStep, onUpdateStep, onCheckStep } from "../lib/firebase/todosData";
const StepInput = ({ step, index, todoId, type }) => {
const [inputValue, setInputValue] = useState(step.title);
const [timer, setTimer] = useState(0);
const onChange = (event, index) => {
setInputValue(event.target.value);
if (timer) {
clearTimeout(timer);
}
const newTimer = setTimeout(() => {
onUpdateStep(todoId, event.target.value, index, type);
}, 1000);
setTimer(newTimer);
};
return (
<div className="input-wrap">
<input
className={step.check ? "check" : ""}
value={inputValue}
onChange={(event) => {
onChange(event, index);
}}
/>
</div>
);
};
export default StepInput;
value의 값은 useState로 ui상에서 즉각적으로 변경이 되도록 하고
timer를 생성하여 timer가 있으면 clearTimeout을 해주고 새로운 timer를 만들어서
Timer에 새로운 Timer를 담아주는 방식이다.
실제 비동기 통신을 해야할 땐 async await으로 활용이 가능하다.
const [inputValue, setInputValue] = useState(step.title);
const [timer, setTimer] = useState(0);
const onChange = (event, index) => {
setInputValue(event.target.value);
if (timer) {
clearTimeout(timer);
}
const newTimer = setTimeout(async() => {
try {
/// api요청
}
catch(error){
console.log(error)
}
}, 1000);
setTimer(newTimer);
};
구현해보고 나니 다른 컴포넌트에도 debounce를 해야해서
costom hook으로 만들어보았다.
useDebounce.js
export const useDebounce = () => {
const [timer, setTimer] = useState(0);
const debounce = (callback, data) => {
if (timer) {
clearTimeout(timer);
}
const newTimer = setTimeout(async () => {
callback(...data);
}, 800);
setTimer(newTimer);
};
return debounce;
};
callback함수와 해당 콜백함수의 파라미터데이터를 인자로 받고
해당 함수를 실행하도록 하였다.
[적용한 컴포넌트의 코드]
const [inputValue, setInputValue] = useState(step.title);
const debounce = useDebounce();
const onChange = (event) => {
setInputValue(event.target.value);
debounce(onUpdateStep, [todoId, event.target.value, index, type]);
};
'React' 카테고리의 다른 글
[React] 이미지 업로드 시 이미지 압축 (0) | 2022.07.06 |
---|---|
[Redux] Redux-Persist (0) | 2022.06.27 |
[React] useRef() 여러 개 한번에 관리하기 (0) | 2022.03.11 |
더미데이터(dummy data) 만들기 / 더미 이미지 사이트 (0) | 2022.03.10 |
[React] create-react-app 없이 react 개발환경 세팅 해보기 (0) | 2022.03.09 |
Comments