당근먹는하니
귀엽고 행복해
당근먹는하니
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 다람쥐🐿 (26)
    • C++ 공부빵야 (7)
    • 공부👻 (5)
    • 프론트엔드✏️ (228)
      • 코드캠프 (120)
      • 팀 프로젝트✨ (31)
      • 개인공부 (67)
    • 프론트엔드 - 바닐라js (7)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘
  • 공통 컴포넌트
  • 팀플
  • javascript
  • 프론트엔드
  • 회고
  • 코드캠프
  • 프로그래머스
  • emotion
  • typescript
  • javascrpit
  • React-hook-form
  • 리액트
  • 배열
  • HTML
  • 코딩
  • JS
  • react
  • 부트캠프
  • 자바스크립트
  • next.js
  • 배포
  • 팀프로젝트
  • 코딩 부트캠프
  • refreshtoken
  • 팀 프로젝트
  • algorithm
  • ssg
  • CSS
  • graphql

최근 댓글

최근 글

티스토리

250x250
반응형
hELLO · Designed By 정상우.
당근먹는하니

귀엽고 행복해

프론트엔드에서 검색을 해보자~~~!!!
프론트엔드✏️/팀 프로젝트✨

프론트엔드에서 검색을 해보자~~~!!!

2022. 7. 29. 18:49
728x90
반응형

 

백엔드에서 search: 인수 받는 게 없을 때 프론트엔드에서만 검색을 해보는 법 !~~~~~~~!!!!!!!!!!

ELK하면 비싸대욤

const [searchedData, setSearchedData] = useState([]);


const onChangeSearchInput = (event) => {
    console.log(event.target.value);
    const filtered = props.themesAll.fetchThemesAll.filter((themeList) => {
      return themeList.title.includes(event.target.value);
    });

    setSearchedData(filtered);
  };

(쓰로틀링이나 디바운싱이 필요할 것 같다.)

 

1. 이렇게 함수를 만들고

 

<S.SearchInput
              placeholder="테마명을 입력하세요."
              onChange={onChangeSearchInput}
            />
            
{searchedData.map((el: IFetchThemes) => (
              <div
                key={uuidv4()}
                onClick={props.onClickTheme(el)}
                style={{ cursor: "pointer" }}
              >
                <S.Flip>
                  <S.Card>
                    <S.Theme src={el.mainImg}>
                      <S.Rank>
                        <S.Ranktext>난이도</S.Ranktext>
                        <S.Star disabled defaultValue={el.rank} />
                      </S.Rank>
                      <S.GenreTag>#{el?.genre.name}</S.GenreTag>
                    </S.Theme>
                    <S.ThemeBack src="https://res.cloudinary.com/dop5piuwp/image/upload/v1658990939/public/theme/card-back_ef6jjd.png">
                      <S.ThemeTitle>{el.title}</S.ThemeTitle>
                      <S.ThemeInfo>
                        이용인원 ~ {el.peoplelimit}명
                        <br />
                        나이제한 {el.agelimit}세
                        <br />
                        {el.intro_title}
                      </S.ThemeInfo>
                    </S.ThemeBack>
                  </S.Card>
                </S.Flip>
              </div>
            ))}

검색된 데이터를 뿌리는 방식으로 했다. 

 

(이미지는 클라우드 오류로 안 나오는 중) 

근데 이렇게 하니까 처음에 아무것도 입력하지 않았을 때 보이는게 없었다. 

searchedData의 초기값을 [] 빈 배열로 설정했기 때문이다.

 

그리고 원래는 searchedData 부분이 props.data?.fetchThemes였는데, 이게 장르별로 분류해서 보여주는 방식이었어서 장르검색이 안됐다. 

 

 

  const [searchedData, setSearchedData] = useState(props.data?.fetchThemes);

const onChangeSearchInput = (event) => {
    console.log(event.target.value);
    const filtered = props.data?.fetchThemes.filter((themeList) => {
      return themeList.title.includes(event.target.value);
    });

    setSearchedData(filtered);
  };

2. 그래서 기본값을 장르로 분류되어 내려온 데이터로 하고, 검색을 하는 데이터 풀도 아예 분류되어온 데이터로 바꿨다.

 

이번엔 searchedData를 undefined로 인식하는(데이터가 내려오기 전에 map을 돌려버리는) 오류가 발생했다. 

이건 뒤에 ?만 붙여주면 된다.

 

{searchedData?.map((el: IFetchThemes) => (

 

그렇게하니 빈게...! 

 

{searchedData && searchedData?.map((el: IFetchThemes) => (

이것도 효과는 없었다..! 

데이터가 있으면, 맵으로 뿌려줘... 그런 느낌이었는데... 

 

검색창에서 뭐라도 입력하지 않으면 테마들이 나오지 않는다. 

위에서 내려온 데이터가 아니라 state를 사용해서 그런 것 같은데 정확한 이유를 모르겠어... 

 

{(searchedData || props.data?.fetchThemes)?.map(

 그래서 searchedData가 없을 땐 props.data?.fetchThemes(장르 분류만 되어서 내려온 데이터)를 보여줘! 했더니 뜬다! 

 

 

잘 되는 줄 알았는데~ 문제!!!!!!

 

공포에서 검색하다가 검색어 지우고 다른 장르를 누르면 그게 안 뜬다~~~~

장르 버튼을 누를 때 onChangeSearchInput 함수는 작동되지 않고 그럼 당연히 setSearchedData도 작동하지 않기 때문에, searchedData의 값엔 변화가 없는 것...

 

 

 그럼 버튼을 누를 때, searchedData에 변화를 주어야할 것 같다.

onClickGenre 했을 때 index, selectAll, genre 이렇게 세 개의 스테이트가 변한다. 아, 근데 전체보기를 눌렀을 때도 생각하면 index를 통해 뭔가 하는 게 나을 것 같다. 약간 불편...한데... 장르의 index가 변할 때니까! 

 

 장르의 index가 변할 때, setSearchedData(장르 분류만 되어온 데이터)를 하고 검색창 input을 비워주면 될 것 같은데? 

아니 그냥 props.data?.fetchThemes가 변할 때 setSearchedData를 하면 될 것 같기도

 

 

이렇게 하니 잘됨! input 초기화가 필요하다!

 

// container
  const searchInputRef = useRef<HTMLInputElement>(null);

// presenter
useEffect(() => {
    setSearchedData(props.data?.fetchThemes);

    props.searchInputRef.current.value = "";
  }, [props.data?.fetchThemes]);

 

겸사겸사 useRef에 타입 지정하는 법도 배웠다! 어렵다 타입스크립트...ㅎㅎㅎ

아무튼 이렇게 직접적으로  Input에 접근할 땐 useRef<HTMLInputElement>(null) 이라고 적어주면 된다!

(props로 넘길 때 타입은 searchInputRef: RefObject<HTMLInputElement>;)

 

1. 장르별 검색

2. 장르 안에서 검색

3. 장르 안에서 검색 후 다른 장르 눌렀을 때 또 다시 장르별 검색

 

  const getDebounce = _.debounce((data) => {
    const filtered = props.data?.fetchThemes.filter((themeList: IFetchThemes) => {
      return themeList.title.includes(data);
    });

    setSearchedData(filtered);
  }, 200)
  
  const onChangeSearchInput = (event: ChangeEvent) => {
    getDebounce((event.target as HTMLInputElement).value);
  };

  useEffect(() => {
    setSearchedData(props.data?.fetchThemes);

    props.searchInputRef.current.value = "";
  }, [props.data?.fetchThemes]);

디바운스도 추가했다! 타입도!! ! 

 

나 정말 뿌듯해!!! 

엉주 매장 검색도 내가 해주기로 했다! 

 

매장검색은 쉽게 끝끝끝

 

 


문제 발생~~~

모바일에선 검색창 없애고 캐러셀이 나오게 해뒀는데, 그거랑 상관없이  useEffect는 setSearchData/searchInputRef 비우기를 수행하기 때문에 오류가 났다. 

 

 useEffect(() => {
    !windowSize && setSearchedData(props.data?.fetchThemes);
    if (!windowSize) props.searchInputRef.current.value = "";
  }, [props.data?.fetchThemes]);

if(!windowSize)를 붙여주었다. 

 

참고로 windowSize는

const [windowSize, setWindowSize] = useState(false);
  const [searchedData, setSearchedData] = useState(props.data?.fetchThemes);

  const handleResize = () => {
    if (window.innerWidth <= 767) {
      setWindowSize(true);
    } else {
      setWindowSize(false);
    }
  };

  useEffect(() => {
    if (window.innerWidth <= 767) {
      setWindowSize(true);
    }
    window.addEventListener("resize", handleResize);
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, [windowSize]);

0주님이 만든 거 갖고 와서 테마에 맞게 쓰고 있다. 

 

 

참고 블로그! 정말 무한감사...ㅠㅠ

https://sunnyfterrain.github.io/devlog/tips-react-search.html

 

[React] 검색 기능 구현 하는법

어떠한 페이지 혹은 프로그램에 거의 필수적으로 들어가는 기능이 있다. 바로 검색 기능! 지금은 크게 어려움이 없지만, 처음 공부하던 시절에는 많이 어려웠었고, 필요한 사람이 있을 수 있으

sunnyfterrain.github.io

 

useRef Type

https://driip.me/7126d5d5-1937-44a8-98ed-f9065a7c35b5

 

728x90
반응형
저작자표시 비영리 동일조건 (새창열림)

'프론트엔드✏️ > 팀 프로젝트✨' 카테고리의 다른 글

팀 프로젝트 room:in us 회고  (0) 2022.08.08
[roominus] 팀 프로젝트 4주차 - 주차별 회고(4)  (0) 2022.08.01
JavaScript heap out of memory - 힙 메모리 누수 확인, 디버깅  (0) 2022.07.28
프론트엔드 부트캠프 78일차, 팀 프로젝트(20) 글은 일인당 하나로 제한합니다.  (0) 2022.07.28
프론트엔드 부트캠프 77일차, 팀 프로젝트(19) 예약한 자에게만 댓글을 허용하노라  (0) 2022.07.27
    '프론트엔드✏️/팀 프로젝트✨' 카테고리의 다른 글
    • 팀 프로젝트 room:in us 회고
    • [roominus] 팀 프로젝트 4주차 - 주차별 회고(4)
    • JavaScript heap out of memory - 힙 메모리 누수 확인, 디버깅
    • 프론트엔드 부트캠프 78일차, 팀 프로젝트(20) 글은 일인당 하나로 제한합니다.
    당근먹는하니
    당근먹는하니

    티스토리툴바