검색 구현하기 in React , React-Native(Flatlist 무한스크롤 프론트에서 구현)

dev.horang🐯·2023년 3월 14일
3

React-Native

목록 보기
13/15

일단 검색 구현에는 두가지 방법이 있다

  1. 서버를 끼고 검색하기
    -> 텍스트를 입력 할 때마다 해당 텍스트를 서버로 보내서 서버에서 일치하는 리스트를 보내주면 해당 리스트를 뿌려준다.
  2. 서버를 끼지 않고 전체 리스트를 받은 후 클라이언트 단에서 검색 구현
    -> 모든 데이터를 서버에서 처음에 받아온 후에 클라이언트에서 텍스트입력시에 필터링한다.

이렇게 두가지 방법이 존재했다. 만약 1번 방법으로 갔을땐 클라이언트 단에서 굉장히 편해진다. 무한스크롤을 따로 직접 자를 필요도 없거니와 그냥 리스트 받아서 뿌려주기만 하면 되기 때문이다. 하지만 서버에 부하가 생길 가능성이 있다. 또한 이전 포스트에서도 말한것 처럼 프로젝트에서 검색의 비중이 그렇게 크지 않아서 클라이언트 단에서 진행하기로 했다.

이런 화면을 만들어보자!

코드는 이렇다. 인풋창에 검색할 때 마다 필터해주는 함수를 넣는다.

  const [search, setSearch] = useState('');
const [myList, setMyList] = useState([]); ->> 전체데이터
const [searchList, setSearchList] = useState([]); ->> 검색해서 걸러진 데이터

...
const updateSearch = (search) => {
    setSearch(search);
    const filtered = myList.filter((itemList) => {
      return (
      itemList.name.toUpperCase().includes(search1.toUpperCase()) ||
        itemList.creatorName?.toUpperCase().includes(search1.toUpperCase())
      );
    });
    setSearchList(filtered);
  };
...
return(
   <TextInput
          onChangeText={updateSearch}
          value={search}
        />
)

이렇게 하면 searchList에 원하는 검색되어 걸러진 리스트 들만 나오게 된다. 위 코드처럼 ||를 사용하면 조건을 추가 할 수 있다.
추가로 영어검색시 대소문자 구분을 없애기 위해 .toUpperCase() 함수를 넣어 입력한 값도 대문자로 데이터값도 대문자로 변환시켜 일치시켜준다.

그리고 이렇게 검색이 끝난 리스트를 map이나 FlatList를 사용하여 뿌려주면 된다.

<FlatList
            data={searchList}
            renderItem={renderItem}
       
          />

하지만 이건 어디까지나 데이터가 적을때 무한스크롤을 사용하지 않고 사용이 가능했던 부분이다. 그럼 이 데이터를 프론트단에서 직접 무한스크롤로 구현하고 싶다면?

  const [listPerPage, setListPerPage] = useState([]);
const [page, setPage] = useState(1);
  const [totalPage, setTotalPage] = useState();
...
  const updateSearch = (search) => {
    setSearch(search);
    const filtered = myList.filter((itemList) => {
      return (
        itemList.name.toUpperCase().includes(search1.toUpperCase()) ||
        itemList.creatorName?.toUpperCase().includes(search1.toUpperCase())
      );
    });
    setSearchList(filtered);
    setTotalPage(Math.ceil(filtered.length / 10)); --> 추가
    setListPerPage(filtered.slice(0, 10)); -->>추가
  };
...
return(
 <FlatList
            data={listPerPage}
            renderItem={renderItem}
            keyExtractor={(item) => item.id}
            initialNumToRender={10}
            maxToRenderPerBatch={10}
            removeClippedSubviews={true}
            onEndReached={() => {
              if (page <= totalPage) {
                setPage(page + 1);
                setListPerPage(
                  listPerPage.concat(
                    searchList.slice(10 * page, 10 * (page + 1)),
                  ),
                );
              }
            }}
            style={{ width: '100%' }}
          />
)

이렇게 FlatList 내부의 onEndReached함수를 사용해서 10개까지 스크롤 다운 했을 때 더 있다면 검색한 리스트에서 또 10개를 잘라 그 뒤에 붙여주는 식으로 진행된다.

막연히 검색이라 하면 당연히 서버를 통해 진행된다고 생각했었는데 해보니까 생각보다 복잡한 로직이였다. 그래도 앞으로 무한스크롤이나 검색관련 로직을 짤때 처음보다 수월하게 짤 수 있을 것 같다.

profile
좋아하는걸 배우는건 신나🎵

0개의 댓글