쿼리스트링 적용하기🌋

Jung Hyun Kim·2020년 7월 15일
1

wecode

목록 보기
41/42

querystring 적용해서 filtering 구현하기🙏🏼

1차 프로젝트 때는 순수 프론트에서 가격 별, 색상 별, 카테고리 별 정렬하는 부분을 구현했는데, 2차 때는 backend에 query string으로 소통해서 filtering을 구현하기로 하였다!

쿼리스트링 함수 설정 시 고려해야 할 부분

  • fetch함수에 백엔드에 필요한 쿼리스트링을 보내줘야 하는데, 페이지, 가격 range검색, 숙소 타입을 순서에 상관없이 클릭해서 적용해야 하고, 하나만 선택할 수도, 모든 걸 선택할수도 있다는 걸 고려해야 하고 함수를 짜야한다.

  • useState로 기본 값을 아래와 같이 filter로 설정해주었다.

const [filters, setFilters] = useState({
    page: '',
    stay_type: '',
    price: '',
  });

쿼리스트링 logic 순서

  • 페이지, 가격, 숙소 타입의 값을 특정 state에 저장해준다.
  • 필터를 적용할 함수를 만들고, 인자에 맞춰서 filters state를 업데이트 해주는 구조를 만든다.
  • 해당 filters state의 객체 안에 값이 없다면 추가하고 값이 있다면 업데이트 해줄 수 있도록 spead operator를 사용해서 해당 객체에 접근해, setFilters를 접목 해준다.
  • filters가 업데이트 될때마다 실행 할 useEffect 함수를 만들어서, 쿼리스트링으로 추가 할 내용을 useState로 업데이트 한다.
  • qs useState 가 데이트 될때마다 useEffect 하는 함수를 만들어서 그때마다 fetch 함수를 실행시키는데 이때, url 뒤에 업데이트 된 qs를 붙여주면 된다!

1. pagination

  • 필요한 페이지 버튼을 만들어 주고, 해당 페이지를 클릭 할때마다 onClick 이벤트 (pageHandler) 함수의 인자로 페이지 num을 넘겨준다.
              <button onClick={() => pageHandler(1)}>1</button>
  • onClick 이벤트의 (pageHandler) 함수에 받은 페이지 numsetPage 값으로 주고, 동시에 쿼리에 맞게 적용한다.
  const pageHandler = async (num) => {
    applyFilter('page', num);
    setPage(num);
  };
  • applyFilter함수에 typepagenum 을 인자로 받아 쿼리스트링에 붙일 내용을 생성해준다. 해당의 경우 type을 'page'로 num 을 '1'로 받았으므로,
    val을 val = &page=${1}로 만들어 주었다.
  const applyFilter = (type, num) => {
    let val;
    if (type === 'page') val = `&page=${num}`;
    else if (type === 'stay_type') val = `&stay_type=${stay_type}`;
    else if (type === 'price') val = `&price=${lowPrice}~${highPrice}`;
    const updatedFilters = { ...filters, [type]: val };
    setFilters(updatedFilters);
  };
  • updatedFilters 변수를 통해 기존의 filters에 spread operator를 적용하고, type값에 접근한 뒤, type 이 있다면 업데이트 하고, 없다면 추가해 준다.
  • 아래와 같이 형태가 될 것이다.
const filters = {
    page: '1',
    stay_type: '',
    price: '',
  };
  • filters가 업데이트 되었을때 실행 할 useEffect 함수를 설정해 주고 기존의 필터에 새로운 내용이 추가되 면 더 해주는 newQs 변수에 setQs로 업데이트 해준다.
  useEffect(() => {
    let newQs = '';
    const keys = Object.keys(filters);
    const filteredKeys = keys.filter((key) => filters[key]);
    filteredKeys.forEach((key) => (newQs += filters[key]));
    setQs(newQs);
  }, [filters]);
  • qs 가 업데이트 될때마다 fetch함수를 만들어 주는데, 이후에 필요한 부분을 querystring으로 넘겨주는 방식이라고 생각하면 된다.

  • prevLoc의 경우 이전 페이지에서 넘겨주는 특정 querystring이 있어서 변수로 지정해서 특정 값이 들어오게 붙인 형태이다.

  useEffect(() => {
    history.push(`/stay${prevLoc}${qs}`);
    fetch(`${API_URL_CH}/stay${prevLoc}${qs}`)
      .then((res) => res.json())
      .then((res) => setData(res.stay_list));
  }, [qs]);

2. price range

  • price range의 경우도 비슷한데, input의 onChange 함수를 사용해서 값을 각 각 lowPrice와 highPrice state 값으로 저장해 준다. 그 뒤 applyFilters에서 값을 전달 받아 적용하는 나머지 또한 동일하다.
const applyFilter = (type, num) => {
    let val;
    if (type === 'page') val = `&page=${num}`;
    else if (type === 'stay_type') val = `&stay_type=${stay_type}`;
    else if (type === 'price') val = `&price=${lowPrice}~${highPrice}`;
    const updatedFilters = { ...filters, [type]: val };
    setFilters(updatedFilters);
  };

3. stay type

  • stay type또한 비슷한데 input type 인 checkbox가 선택되었는지 아닌지를 확인하고 적용하기 위해 inputHandler 로 값을 같이 관리 해주어서 아래와 같이 적용하였다.
onChange={(e) => inputHandler(e, setIsStayTypeChecked, '전체')}
  const inputHandler = (e, set, val) => {
    const target = e.target;
    const { type, checked } = target;
    const value = type === 'checkbox' ? checked : value;
    set(value);
    setStayType(val);
  };
profile
코린이 프론트엔드 개발자💻💛🤙🏼

0개의 댓글