오늘은 리액트 쿼리에 대해 공부했다!
지금 하고 있는 프로젝트에서는 리덕스 툴킷을 사용해 왔는데,
로그인 부분을 맡고 있는 팀원 분이 리덕스 툴킷을 쓰면 너무 복잡해진다고 '리코일'을 쓰자고 제안하셨다.
회의 결과,
로 코드를 짜기로 결정 됐다 !
그래서 오늘은 리액트 쿼리, 내일은 리코일 공부를 하기로 했다.
리액트 쿼리를 공부하던 중 구조분해할당 이라는 것도 알게 되어 같이 정리해보려고 한다.
구조 분해 할당(Destructuring Assignment)
구조 분해 할당은 말 그대로 구조를 분해해서 할당하는 것을 이른다.
만약 test라는 객체가 있고, 그 안의 id를 불러오고 싶은 경우에는
이런 식으로밖에 불러오지 못할 것이다.
하지만 test 안의 id 라는 상당히 복잡한 구조로 불러내야 하기 때문에, 우리는 구조분해할당을 시도할 수 있다.
이처럼 복수로 넣어도 되고 단일로 한 가지만 넣어도 된다.
이것이 구조분해할당이다.
구조분해할당을 한 경우,
console.log(test.id) 가 아닌,
console.log(id)로 불러올 수 있다.
구조분해할당은 이름을 붙일 수도 있다 !
React Query 에 대해
React Query 에는 두 가지 함수가 있다.
상황마다 다르지만 일반적으로 이런 식으로 사용한다.
Query : Read = get
Mutate : Create, Update, Delete = put, patch, delete
왜냐하면 Query 는 자동으로 렌더링(변경) 되는 useEffect 와 같은 성질이고,
Mutate 는 특정 조건을 이수해야만 발동되는 조건형 렌더링이기 때문이다.
--> 가끔 '아이디 중복 체크' 와 같은 '버튼을 클릭' 해야만 발동되게끔 Mutate에 get 요청을 보낼 때도 있다.
React Query를 통해 관리하는 쿼리 데이터는 라이프사이클에 따라 fetching, fresh, stale, inactive, delete 상태를 가진다.
QueryClientProvider
ReactQueryDevtools
서버에서 데이터를 가져오고 캐싱을 하는데 사용하는 기본이며 가장 많이 사용하게 되는 훅이다.
useQuery 훅이 리턴하는 데이터와 옵션의 종류는 매우 다양하다. 주요 사항은 다음과 같다.
리턴 데이터
옵션
삼항연산자를 이용해 isLoading 사용
구조분해할당을 사용했기 때문에 isLoading ? 만으로 적용 가능
만약 구조분해할당을 하지 않았다면?
query 의 isLoading, query 의 data 등으로 사용해야함 !
또한 로딩 중일 때는 객체,
로딩이 끝나면 배열이라 map을 돌릴 수 있다. (data를 불러왔기 때문)
mutate 에 create 라는 이름을 붙였다.
query name 은 생략 가능하다.
axios post 요청은 동일하다.
onSuccess 로 data를 받아온다.
queryClient.invalidateQueries 사용
--> data를 refresh 할 때 사용
포스트 요청을 하거나 삭제 요청을 했을 때 화면에 보여주는 데이터에 변화를 줘야 한다.
그러나 query 키가 변하지 않으므로 강제 refresh 해야할 필요가 있다.
이런 때는 queryClient의 invalidateQueries 메소드를 이용해서 query 키를 날려버린다.
queryClient.invalidateQueries("test");
invalidateQueries에 의해 invalidate(무효화)되면
const queryClient = useQueryClient();
// 캐시에 있는 모든 쿼리를 무효화한다.
queryClient.invalidateQueries()
// todo로 시작하는 모든 쿼리를 무효화한다. ex) ['todos', 1], ['todos', 2], ...
queryClient.invalidateQueries('todos')
// ['todos', 1] 키를 가진 쿼리를 무효화한다.
queryClient.invalidateQueries(['todos', 1])
1번. usemutate 의 queryname은 생략 가능하다.
2번. mutate : modify 로 보내는 데이터는 id, data 값이다.
mutate의 첫 번째 인자에 값이 다 들어가야 하므로
보내야 할 데이터 종류가 2가지 이상이라면,
{ } 객체로 감싸서 한 개의 인자로 보내야 한다.
==> 2 번의 { id, data }
3번.
멀티 이미지가 아닌 1장 이미지 업로드 기준이다.
여기까지는 리덕스 툴킷 사용했을 때와 같다.
modifyImage로 formData 와 config 데이터를 전달해줘야 하기 때문에 { } 중괄호로 감싸야한다.
중괄호를 감싸지 않아 500 에러가 났다 ㅠㅠ..
그리고 리덕스 툴킷과 다르게 리덕스에 저장할 필요가 없기 때문에
저런 식으로 imageUrl을 저장할 필요가 없다 !
이것도 몰라서 엄청 헤맸다 ..
html 까지 profileList.imgPath --> data?.imgPath 로 변경했다 !
리덕스 툴킷에서 리액트 쿼리로 변경 완료 ..!