React | Context API, 조건에 맞는 get 요청

샘샘·2023년 5월 11일
0

React

목록 보기
20/31
post-thumbnail

미니프로젝트 트러블 슈팅

👉 항해99 14기 미니프로젝트주차 6조

😭 Search 컴포넌트에서 생성한 값을 List 컴포넌트에서 넘겨받아 get 요청을 해서 데이터를 출력해야 하는 상황 (부모자식이 아닌 서로 다른 컴포넌트)

😭 기존에 받아오던 get Api와 중복되지 않게 조건에 따라서 새로운 get 요청을 해야하는 상황

// MainSearch.jsx
const searchSubmit = () => {
        if (selectWhere.value == 'null' && starRadio.length == 0 && keyword == '') {
            alert("한가지 이상의 조건을 선택하신 후, '검색하기'를 눌러주세요 😉")
        }
        else if (selectWhere.value == 'null' && starRadio.length == 0 && keyword.length >= 1) {
            setSearch(`&keyword=${keyword}`)
        }
        else if (selectWhere.value == 'null' && starRadio.length >= 1 && keyword == '') {
            setSearch(`&star=${starRadio}`)
        }
        else if (selectWhere.value !== 'null' && starRadio.length == 0 && keyword == '') {
            setSearch(`&location=${selectWhere.label}`)
        }
        else if (selectWhere.value !== 'null' && starRadio.length >= 1 && keyword == '') {
            setSearch(`&location=${selectWhere.label}&star=${starRadio}`)
        }
        else if (selectWhere.value !== 'null' && starRadio.length == 0 && keyword.length >= 1) {
            setSearch(`&location=${selectWhere.label}&keyword=${keyword}`)
        }
        else if (selectWhere.value == 'null' && starRadio.length >= 1 && keyword.length >= 1) {
            setSearch(`&star=${starRadio}&keyword=${keyword}`)
        }
        else if (selectWhere.value !== 'null' && starRadio.length >= 1 && keyword.length >= 1) {
            setSearch(`&location=${selectWhere.label}&star=${starRadio}&keyword=${keyword}`)
        }
    }

사용자가 필터링 한 조건에 따라서 get요청을 하기 위해 api를 state로 관리하고 있다

그런데 이 state가 있는 search 컴포넌트는 검색 기능만 가능하기 때문에, 실제 데이터를 출력해주는 list 컴포넌트로 state를 보내줘야 한다

  1. 초기 시도

redux toolkit을 사용해서 공통으로 쓰일 state를 관리하려고 했다

  1. 실패 이유

조건에 따른 값을 생성해야 하는데, redux toolkit을 사용하면 더 복잡해질 것이라고 판단했다

  1. 해결 방법

Context API를 사용해서 전역으로 사용될 수 있는 state를 만들었다

// SearchContext.js
import { createContext, useContext, useState } from "react";

export const SearchContext = createContext(undefined)

export function SearchContextProvider({children}) {
    const [search, setSearch] = useState('')

    const value = { search, setSearch, }

    return <SearchContext.Provider value={value}>{children}</SearchContext.Provider>
}

export function useSearchContext() {
    return useContext(SearchContext)
}
// MainSearch.jsx
function MainSearch() {
    const { setSearch } = useSearchContext()
    const search = useSearchContext()
// MainList.jsx
function MainLists() {
    const search = useSearchContext()

각 컴포넌트의 상수에 Context를 할당해줘서 같은 값을 관리할 수 있게 한다

// MainList.jsx
const filter = search.search

search 컴포넌트에서 생성한 search 값을 list 컴포넌트에서 사용할 수 있게 상수로 할당한다

// MainList.jsx
const getBoard = async (filter) => {
        if (!filter) {
            const response = await axios.get(`/api/boards?season=${season}`)
            return response.data.data
        } else {
            const response = await axios.get(`/api/boards?season=${season}${filter}`)
            return response.data.data
        }
    }

const { data: board } = useQuery(['board', season, filter], () => getBoard(filter))

필터링을 해야 search에 값이 생성되므로, 필터링을 하지 않았을 때(상수 filter에 값이 없을 때)는 기존에 받아오던 get Api를 요청하고, 필터링을 했을 때의 get Api에 값이 바뀌어야 하는 자리에 템플릿 리터럴로 filter를 받아와서 요청한다

useQuery의 쿼리키가 바뀔 때마다 데이터를 받아와야 하므로, 기존에 있던 board와 season에서 추가로 filter를 넣어준다

profile
회계팀 출신 FE개발자 👉콘테크 회사에서 웹개발을 하고 있습니다

0개의 댓글