본문 바로가기
React

[React Query] 리액트 쿼리 적용(1)

by codnjs779 2022. 4. 25.

출처: Codevolution - React Query Tutorial ch. 1~ 10

https://www.youtube.com/watch?v=VtWkSCZX0Ec&list=PLC3y8-rFHvwjTELCrPrcZlo6blLBUspd2 

 

회사에서 진행 중인 미니 프로젝트 코드를 작성하다가 전부터 궁금했던 리액트 state관리에 대해서 질문을 드렸다.

 

Api요청에 대한 응답을 state에 넣어서 관리를 하면, Data fetch가 완료되지 않았을 때는 항상 빈 state인데 이럴 때마다 항상 useEffect나 조건문을 넣어서 해결하는 방법밖에 없는지 궁금했다. 이전에 혼자서 프로젝트를 만들어 볼 때는 보통 앞서 언급했던 방법으로 해결했었는데 매번 할 때마다 좀,, 뭔가 최선은 아닌 거 같아서 찝찝했는데 다른 방법은 없는 듯해서 그냥 진행했었다. (구글링을 너무 대충 해본 게 아닐까,,,?😂)

 

이런 문제를 질문드렸을 때, 리액트 쿼리를 한번 사용해보라고 하셔서 일단 필요한 부분만 뽑아서 적용시켜봤다. 사용해보니 정말 유용하다고 느꼈다. 그동안 귀찮게 여러 줄 장황하게 썼던 코드가 간결하게 정돈되는 것을 보고 잘 정리해두고 응용해서 잘 써보고 싶어서 괜찮은 유튜브 동영상을 찾아서 정리해두려 한다.

1) Fetching Data 

이전에 리액트로 API통신을 하기 위해서 작성해야하는 코드는 대략 이런 형태였을 것이다.
 
const [isLoading, setIsLoading] = useState(true)
  const [data, setData] = useState([])
  const [error, setError] = useState('')

  useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/todos/').then(res => {
      setData(res.data)
      setIsLoading(false)
    }).catch(error => {
      setError(error.message)
      setIsLoading(false)
    })
  }, [])

  if (isLoading) {
    return <h2>Loading...</h2>
  }

  if(error) {
    return <h2>{error}</h2>
  }

  return (
    <>
      <h2>Super Heroes Page</h2>
      {data.map(item => {
        return <div>{item.title}</div>
      })}
    </>
  )​
 
에러발생, 로딩중 일 때 상태를 state로 관리해줘야하고 useEffect를 사용해서 페이지가 로드 될 때 발생해야하는 동작들을 관리해줘야했다. 리액트 쿼리를 사용하게 되면, state로 관리하던 fetch상태를 한번에 관리할 수 있는 장점이 있다. 
개선한 코드는 아래와 같다. 
 
 
const fetchTodos = () => {
    return axios.get('https://jsonplaceholder.typicode.com/todos/')
}

const RQSuperHeroes = () => {
    const {isLoading, data, isError, error, isFetching} = useQuery('todos', fetchTodos)

    if(isLoading) {
        return <h2>Loading...</h2>
    }
    if(isError) {
        return <h2>{error.message}</h2>
    }
    return (
        <>
            <h2>rq super page</h2>
            {
                data?.data.map(item => {
                    return <div>
                        {item.title}
                    </div>
                })
            }</>)}
 

 fetch상태를 state로 관리하지 않아도 돼서 훨씬 코드가 간결해진 것을 확인할 수 있다. useQuery에 상태가 모두 정의되어있고 그걸 상황에 따라서 사용해주면 되니까 너무 유용했다.👍 에러 메시지 관리도 편하게 할 수 있다.

 

2) Query Cache

리액트 쿼리는 한번 데이터를 불러오면 그 이후로는 이미 캐시에 저장된 데이터를 사용한다. 성공적으로 data를 불러오면, 그 데이터를 보관해서 매번 데이터를 요청하지 않게 한다. 캐시에 저장된 데이터를 사용함.

 이 기능은 여러 컴포넌트에서 데이터를 사용해야 할 때 부담 없이 사용할 수 있도록 한다. 리액트에서 데이터를 전역으로 관리하거나 하는 게 아니면 props을 해서 데이터를 주고받아야 하는 구조가 많이 생기는데 이것도 안 할 수 있게 된다!

 

 

그 외) stale time,  Refetch Defaults, polling, enable은 아직 실제 적용을 해보지 않아서 쓰임새가 와닿지 않아서 추후에 정리할 예정! 

 


 

리액트를 사용하면서 리덕스나 실행 콘텍스트를 통해서 전역으로 데이터를 관리하는 방법을 잘 이용해 본 적은 없었다. 실행 콘텍스트는 이해하고 몇 번 써보기는 했지만 특히 리덕스는 연습으로 몇 번 해봤을 때 뭔가 이해가 될 듯 말 듯하고 ㅠ 연습 예제 코드로 따라 하면 알거같다가도 개인 프로젝트에서 활용해보려고 하면 왜 이렇게 어렵게 느껴지고 혼자 코드를 못쓰겠는지,,,😥 

 

리덕스가 없어도 리액트 쿼리를 이용해서  데이터를 필요한 위치에서 prop 없이 사용하거나, state관리를 간결하게 할 수 있는 등 여러모로 리액트를 사용하면서 고민했던 문제들을 해결할 수 있어서 만족했다. 

 

앞으로 프로젝트에 리액트 쿼리를 좀 더 다양하게 적용해보고 싶다.

 

다음 리액트 쿼리 포스팅은 핵심 구동원리와 강의 11~20에서 남기고 싶은 내용 위주로 정리하려고 한다. 

공식문서도 정리가 잘 되어있어서 추가적으로 내용을 보강할 예정이다.