useState
로 선언하고 onChange
이벤트로 입력값을 setState
로 업데이트 해준다.!searchKeyword &&
기존에 보여줬던 게시글 리스트를 보여준다.searchKeyword &&
기존에 보여주던 게시글 리스트는 보여주지 않고 검색어에 맞게 나온 리스트를 보여준다.menu
라는 string 타입의 값은 페이지 진입 시, 어느 게시판 테이블의 데이터를 가져오거나 검색을 하는지를 알 수 있는 값이다.
그리고 디바운스를 사용함으로 어느정도의 최적화도 고려해주었다.
export const useBoardSearch = (menu: string) => {
const [searchKeyword, setSearchKeyword] = useState("");
const [searchResult, setSearchResult] = useState<DocumentData[]>([]);
useEffect(() => {
const searchBoardFunc = _.debounce(async () => {
const q = query(
collection(firebaseDb, menu), // 포스트 컬렉션
orderBy("title"), // 제목 정렬
startAt(searchKeyword),
endAt(searchKeyword + "\uf8ff")
);
const resSnap = await getDocs(q);
const searchData = resSnap.docs.map((doc) => doc.data());
setSearchResult(searchData);
}, 1000);
searchBoardFunc();
}, [searchKeyword]);
return [searchKeyword, setSearchKeyword, searchResult] as const;
};
export default function Board(props: { menu: string }) {
// search board
const [searchKeyword, setSearchKeyword, searchResult] =
useBoardSearch(menu);
return (
<Boards.Wrapper>
<div style={{ position: "relative" }}>
<SearchBoardInput setSearchKeyword={setSearchKeyword} />
</div>
<Boards.BoardListBox>
{!searchKeyword &&
boardData.map((el, index) => (
<Boards.Board
key={index}
id={el.id}
onClick={moveToDetail}
isDark={darkMode}
>
<Boards.BoardNumber>
{boardListData.length -
(page - 1) * limit -
index}
</Boards.BoardNumber>
<Boards.BoardTitle>
{el.title}
</Boards.BoardTitle>
<Boards.Name>{el.name}</Boards.Name>
<Boards.BoardDate>
{
el.timestamp
.toDate()
.toISOString()
.split("T")[0]
}
</Boards.BoardDate>
</Boards.Board>
))}
{searchKeyword &&
searchResult.map((el, index) => (
<Boards.Board
key={index}
id={el.id}
onClick={moveToDetail}
isDark={darkMode}
>
<Boards.BoardNumber>
{searchResult.length - index}
</Boards.BoardNumber>
<Boards.BoardTitle>
{el.title}
</Boards.BoardTitle>
<Boards.Name>{el.name}</Boards.Name>
<Boards.BoardDate>
{
el.timestamp
.toDate()
.toISOString()
.split("T")[0]
}
</Boards.BoardDate>
</Boards.Board>
))}
</Boards.BoardListBox>
</div>
</Boards.Wrapper>
);
}