2차 공부/TIL

24.08.30 팀프로젝트 Startify 진행상황

공대탈출 2024. 8. 31. 00:26

오늘은 검색페이지 작업을 진행했다.

 

import styled from "styled-components";
import Button from "../components/common/Button";
import PostItem from "../components/home/PostItem";
import useSearchedMusicContext from "../hooks/useSearchedMusicContext";

const Search = () => {
    const { searchText, handleSearchText, SearchHandle, searchedSongs } = useSearchedMusicContext();

    return (
        <ListWrapper>
            <div>
                <input value={searchText} onChange={handleSearchText} />
                <Button onClick={SearchHandle}>검색</Button>
            </div>
            <ListUl>
                {searchedSongs ? (
                    searchedSongs.map((music) => {
                        return <PostItem key={music.id} music={music} />;
                    })
                ) : (
                    <div>해당하는 노래가 없습니다.</div>
                )}
            </ListUl>
        </ListWrapper>
    );
};

export default Search;

 

아직 컴포넌트 분리는 진행하지 않았는데, 검색페이지에 context provider으로 감싸는데 어려움을 겪었었다.

<Routes>
    <Route path="" element={<Layout />}>
        <Route path="/" element={<Home />} />
        <Route path="/search" element={<Search />} />
        <Route path="/detail" element={<Detail />} />
        <Route path="/profile" element={<Profile />} />
        <Route path="/profile/*" element={<Profile />} />
        <Route path="/form" element={<Form />} />
        <Route path="/modify-profile" element={<ModifyProfile />} />
    </Route>
    <Route path="/login" element={<Login />} />
    <Route path="/signup" element={<SignUp />} />
    <Route path="*" element={<NotFound />} />
</Routes>

기존 라우터는 이러했다.

하지만 검색페이지에 context로 상태를 공유하면서 Router에 Provider을 사용해야했는데, Routes안에는 Provider을 사용하지 못하는 문제가 있었다.

그래서 element에서 원하는 Provider으로 감쌌다.

<Routes>
    <Route path="" element={<Layout />}>
        <Route
            path="/"
            element={
                <MusicProvider>
                    <Home />
                </MusicProvider>
            }
        />
        <Route
            path="/search"
            element={
                <SearchedMusicProvider>
                    <Search />
                </SearchedMusicProvider>
            }
        />
        <Route path="/detail" element={<Detail />} />
        <Route path="/profile" element={<Profile />} />
        <Route path="/profile/*" element={<Profile />} />
        <Route path="/form" element={<Form />} />
        <Route path="/modify-profile" element={<ModifyProfile />} />
    </Route>
    <Route path="/login" element={<Login />} />
    <Route path="/signup" element={<SignUp />} />
    <Route path="*" element={<NotFound />} />
</Routes>

이렇게 element를 감싸면 Provider으로 context에서 데이터를 뽑아서 사용할 수 있다.

createBrowserRouter을 사용해서 라우터를 만들었다면 좀 더 쉽게 했을것 같은데 BrowserRouter으로 하려다보니 어려움을 겪었던 것 같다.


원래 노래 제목만으로 검색을 제한하려했으나 너무 이상한 검색기능이라고 생각돼 변경하였다.

데이터의 노래제목, 가수명, 게시글제목 모두에서 검색하여 키워드가 있다면 데이터를 주는 것으로 설정하였다.

 

const getFilteredData = async (value) => {
    const { data, error } = await supabase
        .from("STARTIFY_DATA")
        .select("postTitle, name, title, url, genre, likes, id")
        .or(`title.ilike.%${value}%,postTitle.ilike.%${value}%,name.ilike.%${value}%`);
    if (error) {
        console.log("getAllData error :>> ", error);
        return;
    }
    if (data) {
        setSearchedSongs(data);
        console.log("data :>> ", data);
    }
};

 

  • title.ilike.%${value}%: title 컬럼의 값이 ${value}를 포함하는지 여부를 확인합니다. 여기서 ilike는 대소문자를 구분하지 않고 비교하는 연산자입니다. %${value}%는 SQL의 와일드카드 패턴 매칭을 의미하며, ${value}가 문자열의 어디에든 위치할 수 있음을 나타냅니다.
  • postTitle.ilike.%${value}%: postTitle 컬럼에서 ${value}를 포함하는지 확인합니다.
  • name.ilike.%${value}%: name 컬럼에서 ${value}를 포함하는지 확인합니다.

SQL문법이어서 대충 느낌만 알고있으면 될 것 같다.