일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 템플릿스트링
- 결합선택자
- JS예제
- 부트캠프 #코딩 #개발일지 #프론트엔드 #CSS #TIL
- 개발일지 #TIL #프론트엔드 #HTML
- textContent
- React
- 특성선택자
- 부트캠프 #개발일지 #TIL #FlexboxFroggy #displayflex #flexbox
- appendChild
- Til
- 부트캠프 #CSS #개발일지 #TIL
- ㅜㄹㄹ
- 부트캠프 #개발일지 #TIL #CSS속성 #float #clear
- useEffect
- CSS
- 부트캠프 #CSS #개발일지 #TIL #박스모델
- 알고리즘
- js
- 깃허브오류
- 부트캠프 #개발일지 #TIL #Position #위치
- 부트캠프 #개발일지 #TIL #그리드 #CSS
- 부트캠프 #스파르타코딩클럽 #개발일지# #html
- 리액트
- 부트캠프 #스파르타코딩클럽 #개발일지# #TIL #Javascript #confirm #location.href
- 부트캠프
- querySelector
- useState
- 의사클래스
- 개발일지
- Today
- Total
나의 개발일지
[React] React query로 TodoList 리팩토링하기 본문
< 설치해야 할 것들! >
yarn add axois
yarn add json-server
json-server --watch db.json --port 번호
yarn add react-query
src > App.jsx
import React from "react";
import Router from "./shared/Router";
import { QueryClientProvider, QueryClient } from "react-query";
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<Router />;
</QueryClientProvider>
);
};
export default App;
QueryClientProvider : 데이터를 읽어오는 기능(QueryClient)을 애플리케이션 전체에 주입하도록 하는 API
< 조회 기능 구현 >
src > api > todos.js
// axios 요청이 들어가는 모든 모듈
import axios from "axios";
// 조회
const getTodos = async () => {
const response = await axios.get(`${process.env.REACT_APP_SERVER_URL}/todos`);
console.log("response", response.data);
return response.data;
};
export { getTodos};
.env 파일 만들어서 localhost를 변수에 담아준다.
우리가 필요한 값은 response의 data !
export 잊지말자!
src > redux > components > TodoList.jsx
import { getTodos } from "../../../api/todos";
import { useQuery } from "react-query";
function TodoList({ isActive }) {
// const todos = useSelector((state) => state.todos); // 리덕스 방식
const { isLoading, isError, data } = useQuery("todos", getTodos);
console.log("data", data);
if (isLoading) {
return <h1>로딩중입니다!!!!!!</h1>;
}
if (isError) {
return <h1>오류가 발생했습니다!!!!</h1>;
}
// 코드 생략
return (
// todos 대신 가져온 data 넣기
{data
.filter((item) => item.isDone === !isActive)
.map((item) => {
return <Todo key={item.id} todo={item} isActive={isActive} />;
})}
)
const { isLoading, isError, data } = useQuery("todos", getTodos);
구조분해할당으로 가져오기
useQuery의 key(todos)가 중요하다. 그 이유는 이따가 밑에서 설명하겠다
이 부분이 React Query가 가지고 있는 큰 장점이다.
Thunk를 쓸 땐, 초기값으로 isLoading, isError등을 직접 만들어야했다.
return 문에 도착하기 전에 isLoading 또는 isError에 따라 별도의 처리를 해주기 때문에 대기상태 처리 / 오류 처리에 대한 부분도 아주 쉽게 해결이 된다! 신세계를 경험 중..
< 추가 기능 구현 >
src > api > todos.js
// axios 요청이 들어가는 모든 모듈
import axios from "axios";
// 조회
const getTodos = async () => {
const response = await axios.get(`${process.env.REACT_APP_SERVER_URL}/todos`);
console.log("response", response.data);
return response.data;
};
// 추가
const addTodo = async (newTodo) => {
await axios.post(`${process.env.REACT_APP_SERVER_URL}/todos`, newTodo);
};
export { getTodos, addTodo };
src > redux > components > Input.jsx
import { addTodo } from "../../../api/todos";
import { useMutation, useQueryClient } from "react-query";
function Input() {
// const dispatch = useDispatch();
// 리액트 쿼리 관련 코드
const queryClient = useQueryClient();
const mutation = useMutation(addTodo, {
onSuccess: () => {
queryClient.invalidateQueries("todos"); // useQuery key 가 중요! // todos를 무효화
console.log("성공하였습니다!");
},
});
// 추가하려는 todo를 newTodo라는 객체로 세로 만듦
const newTodo = {
title,
contents,
isDone: false,
id: uuidv4(),
};
// dispatch(addTodo(newTodo)); // 원래 dispatch를 통해 실행시켰었음
mutation.mutate(newTodo);
// state 두 개를 초기화
setTitle("");
setContents("");
};
Invalidate and refresh 이렇게 하면,
todos라는 이름으로 만들었던 query를 invalidate 할 수 있다
[invalidate의 과정]
Input.jsx에서 값 입력으로 인해 서버 데이터가 변경됨
→ onSuccess가 일어나면 기존의 Query인 “todos”는 무효화
→ 새로운 데이터를 가져와서 “todos”를 최신화시킴
→ TodoList.jsx를 갱신함
따라서 계속해서 리액트 앱은 최신 상태의 서버 데이터를 유지할 수 있게 되는 것
ex ) 만약 20:00에 todos의 데이터가 20개인데 3개가 더 추가되어서 21:00에 23개가 됐는데
서버에만 저장되어있지만 렌더링하기 전까진 추가된 값이 보여지지 않는다. 그래서 invalidate를 쓰는 것이다
useQuery
import { useQuery } from 'react-query';
import { fetchTodoList } from '../api/fetchTodoList';
function App() {
const info = useQuery('todos', fetchTodoList);
}
- 첫 번째 인자 ‘todos’ --> 쿼리의 키(Query Keys)
- refetching 처리 ( invalidate )
- 캐싱(caching) 처리
- 애플리케이션 전체 맥락에서 이 쿼리를 공유하는 방법으로 쓰인다.
—> 그 어느 컴포넌트 곳곳에 촥촥 뿌려져 있어도 같은 key면 같은 쿼리 및 데이터 보장!!
- 두 번째 인자, ‘fetchTodoList’ --> 쿼리 함수(Query Functions) 비동기 함수
- 쿼리 함수는 promise 객체를 return
- promise 객체는 반드시 data를 resolve하거나 에러 (resolve는 정상적으로 통신되었음을 의미 )
mutations
- CUD에서 사용된다
useMutation --> hook, 함수, API
mutation.mutate( 인자 )
- 인자는 반드시 한 개의 변수 또는 객체여야 한다
- mutation.mutate( 인자1, 인자2 ) --> 오류
- 결과는 객체형태이다
- onSuccess일때는 꼭 Query key 사용!
'React' 카테고리의 다른 글
React-hook-form으로 로그인/회원가입 유효성 검사 (0) | 2024.01.02 |
---|---|
[React] react-query 강의 내용 정리 (1) | 2023.12.20 |
[React] 에러 발생 및 해결 Cannot read properties of undefined (1) | 2023.11.23 |
[React] JSON과 비동기통신 실습 (2) | 2023.11.14 |
[React] React Hooks - useState / useEffect / useRef (0) | 2023.11.09 |