보통 검색 기능을 구현할 때 filter 메서드를 사용한다.
firebase의 내장 기능을 이용하면 쉽게 검색기능을 구현할 수 있다.
const { onLoadedIngredients } = props;
const [enteredFilter, setEnteredFilter] = useState("");
useEffect(() => {
const query =
enteredFilter.length === 0
? ""
: `?orderBy="title"&equalTo="${enteredFilter}"`;
fetch("url..." +query)
.then((res) => res.json())
.then((responseData) => {
const loadedIngredients = [];
for (let key in responseData) {
loadedIngredients.push({
id: key,
title: responseData[key].title,
amount: responseData[key].amount,
});
}
onLoadedIngredients(loadedIngredients);
});
}, [enteredFilter, onLoadedIngredients]);
<input
type="text"
value={enteredFilter}
onChange={(e) => setEnteredFilter(e.target.value)}
/>
fetch API 엔드 포인트 뒤에 전달해줄 query를 작성한다.
?orderBy="...DB에 찾고자 하는 키 값"&equalTo="${...입력받은 값}"
const query = enteredFilter.length === 0 ? "" : `?orderBy="title"&equalTo="${enteredFilter}"`;
이렇게 구현해도 작동은 잘 하지만, 인풋창에 입력할 때 마다 서버에 request를 보내게된다.
불필요한 request를 줄이기 위한 방법으로 setTimeout을 사용할 수 있다.
useEffect(() => {
const timer = setTimeout(() => {
if(enteredFilter === inputRef.current.value) {
const query =
enteredFilter.length === 0
? ""
: `?orderBy="title"&equalTo="${enteredFilter}"`;
fetch(
"...url" +
query
)
.then((res) => res.json())
.then((responseData) => {
const loadedIngredients = [];
for (let key in responseData) {
loadedIngredients.push({
id: key,
title: responseData[key].title,
amount: responseData[key].amount,
});
}
onLoadedIngredients(loadedIngredients);
});
}
}, 300);
return () => {
clearTimeout(timer);
}
}, [enteredFilter, onLoadedIngredients, inputRef]);
setTimeout 함수 안에 조건문을 추가하여
지정한 시간마다 state 값과 inputRef 값을 비교하고, 값이 같을때만 서버에 request를 보낸도록 한다.
또한 clearTimeout을 하지않으면 여러개의 타이머가 작동되어 불필요한 메모리가 쌓일 수 있으니 마지막에 clearTimeout을 리턴하도록 한다.