import { useState, useEffect } from "react";
import "../DebounceHook.css";
// 함수에 사용자가 검색한 검색어를 넣어주면 검색어에 따라 필터링된 결과물을 반환
function fetchDataFromServer(value) {
// 만약 value가 비어있으면 빈 배열 반환
if (!value) {
return [];
}
console.log("서버로부터 데이터를 가져오는중...");
const users = [
{ name: "차은우", age: "27" },
{ name: "이동민", age: "23" },
{ name: "이동수", age: "32" },
{ name: "손흥민", age: "33" },
{ name: "조규성", age: "29" },
{ name: "최우식", age: "25" },
{ name: "차승원", age: "40" },
];
// value로 시작하는 것들로만 필터링해서 반환
return users.filter((user) => user.name.startsWith(value));
}
function DebounceHook() {
// 검색어를 관리해줄 state
const [input, setInput] = useState("");
// 결과물을 관리해줄 state
const [result, setResult] = useState([]);
// input이 변경될때마다 반응
useEffect(() => {
const users = fetchDataFromServer(input);
setResult(users);
}, [input]);
return (
<div className="container">
<div className="search-container">
<input
placeholder="검색어를 입력해주세요"
value={input}
onChange={(event) => setInput(event.target.value)}
/>
<ul>
{result.map((user) => (
<li key={user.name}>
<span>{user.name}</span>
<span>{user.age}세</span>
</li>
))}
</ul>
</div>
</div>
);
}
export default DebounceHook;
Debounce 적용 코드
import { useState, useEffect } from "react";
import "../DebounceHook.css";
// 함수에 사용자가 검색한 검색어를 넣어주면 검색어에 따라 필터링된 결과물을 반환
function fetchDataFromServer(value) {
// 만약 value가 비어있으면 빈 배열 반환
if (!value) {
return [];
}
console.log("서버로부터 데이터를 가져오는중...");
const users = [
{ name: "차은우", age: "27" },
{ name: "이동민", age: "23" },
{ name: "이동수", age: "32" },
{ name: "손흥민", age: "33" },
{ name: "조규성", age: "29" },
{ name: "최우식", age: "25" },
{ name: "차승원", age: "40" },
];
// value로 시작하는 것들로만 필터링해서 반환
return users.filter((user) => user.name.startsWith(value));
}
function DebounceHook() {
// 검색어를 관리해줄 state
const [input, setInput] = useState("");
const [debouncedInput, setDebouncedInput] = useState(input);
// 결과물을 관리해줄 state
const [result, setResult] = useState([]);
// 사용자가 타이핑을 한 후 1초가 지난 다음 input안의 결과물을 debouncedInput에 넣어주기
useEffect(() => {
// setTimeout은 생성된 타이머의 식별자를 반환하는데, 식별자를 clearTimeout이라는 함수에 넣고 호출해주면 타이머를 취소할 수 있음
const timerID = setTimeout(() => {
console.log("콜백호출");
setDebouncedInput(input);
}, 1000);
// useEffect의 return값으로 콜백함수를 넣어주면 콜백함수는 다음 useEffect가 실행되기 이전에 실행됨
return () => {
clearTimeout(timerID);
};
}, [input]);
// input이 변경될때마다 반응
useEffect(() => {
const users = fetchDataFromServer(input);
setResult(users);
}, [input]);
return (
<div className="container">
<div className="search-container">
<input
placeholder="검색어를 입력해주세요"
value={input}
onChange={(event) => setInput(event.target.value)}
/>
<ul>
{result.map((user) => (
<li key={user.name}>
<span>{user.name}</span>
<span>{user.age}세</span>
</li>
))}
</ul>
</div>
</div>
);
}
export default DebounceHook;
정리
DebounceHook
import { useState, useEffect } from "react";
import "../DebounceHook.css";
import { useDebounce } from "../hooks/debounceHook2";
// 함수에 사용자가 검색한 검색어를 넣어주면 검색어에 따라 필터링된 결과물을 반환
function fetchDataFromServer(value) {
// 만약 value가 비어있으면 빈 배열 반환
if (!value) {
return [];
}
console.log("서버로부터 데이터를 가져오는중...");
const users = [
{ name: "차은우", age: "27" },
{ name: "이동민", age: "23" },
{ name: "이동수", age: "32" },
{ name: "손흥민", age: "33" },
{ name: "조규성", age: "29" },
{ name: "최우식", age: "25" },
{ name: "차승원", age: "40" },
];
// value로 시작하는 것들로만 필터링해서 반환
return users.filter((user) => user.name.startsWith(value));
}
function DebounceHook() {
// 검색어를 관리해줄 state
const [input, setInput] = useState("");
// 0.3초 딜레이
const debouncedInput = useDebounce(input, 300);
// 결과물을 관리해줄 state
const [result, setResult] = useState([]);
// debouncedInpu이 변경될때마다 반응
useEffect(() => {
const users = fetchDataFromServer(debouncedInput);
setResult(users);
}, [debouncedInput]);
return (
<div className="container">
<div className="search-container">
<input
placeholder="검색어를 입력해주세요"
value={input}
onChange={(event) => setInput(event.target.value)}
/>
<ul>
{result.map((user) => (
<li key={user.name}>
<span>{user.name}</span>
<span>{user.age}세</span>
</li>
))}
</ul>
</div>
</div>
);
}
export default DebounceHook;
커스텀 훅
import { useState, useEffect } from "react";
// value - 이벤트 발생으로 인해 변경되는 값 (여기에서는 input을 의미)
// delay - 마지막 이벤트가 발생하고 기다리는 시간을 의미
// debouncedValue - debounce가 적용된 값(debouncedinput을 의미)
// input이 아니라 다른 경우에도 Custom Hook을 사용할 수 있도록 debouncedInput 대신 debouncedValue사용
export function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
// setTimeout은 생성된 타이머의 식별자를 반환하는데, 식별자를 clearTimeout이라는 함수에 넣고 호출해주면 타이머를 취소할 수 있음
const timerID = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// useEffect의 return값으로 콜백함수를 넣어주면 콜백함수는 다음 useEffect가 실행되기 이전에 실행됨
return () => {
clearTimeout(timerID);
};
}, [value, delay]);
return debouncedValue;
}
정리
**- Debounce는 함수의 호출 횟수를 제한하여 리소스 낭비를 줄여줌