728x90
반응형
Lv5
- Lv4의 과제에서 Redux를 react-query로 리팩토링 합니다.
Keyword
query
1. React-Query 설치
yarn add react-query
2. index.tsx
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import GlobalStyle from './GlobalStyles';
import { QueryClient, QueryClientProvider } from 'react-query';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient}>
<GlobalStyle />
<App />
</QueryClientProvider>
);
1) QueryClinetProvider 설정
▼참고 ▼
3. src > queryApi.ts
import api from './api';
import { Todo } from '../types/Todo';
//조회
const getTodos = async () => {
const response = await api.get('/todos');
return response.data;
};
//추가
const addTodos = async (newData: Todo) => {
await api.post(`/todos/`, newData);
};
//삭제
const deleteTodos = async (id: string) => {
await api.delete(`/todos/${id}`);
};
//변경
const changeTodos = async ({ id, isDone }: { id: string; isDone: boolean }) => {
await api.patch(`/todos/${id}`, { isDone: !isDone });
};
export { getTodos, addTodos, deleteTodos, changeTodos };
1) 변경 부분 : 객체 하나로 묶어서 전달
4. src > InputForm.tsx (추가)
import React, { useState } from 'react';
import uuid from 'react-uuid';
import styled from 'styled-components';
import { useMutation, useQueryClient } from 'react-query';
import { addTodos } from '../axios/queryApi';
function InputForm() {
const queryClient = useQueryClient();
const mutation = useMutation(addTodos, {
onSuccess: () => {
queryClient.invalidateQueries('todos');
},
});
const [title, setTitle] = useState<string>('');
const [content, setContent] = useState<string>('');
const inputTitle = (e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
};
const inputContent = (e: React.ChangeEvent<HTMLInputElement>) => {
setContent(e.target.value);
};
const formSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (title === '' || content === '') {
alert('제목/내용 모두 입력해야합니다.');
return;
}
const newData = {
id: uuid(),
title,
content,
isDone: false,
};
mutation.mutate(newData);
setTitle('');
setContent('');
};
return (
<StForm onSubmit={formSubmit}>
<label>제목</label>
<input value={title} onChange={inputTitle}></input>
<label>내용</label>
<input value={content} onChange={inputContent}></input>
<button type="submit">추가하기</button>
</StForm>
);
}
export default InputForm;
1) useQueryClient()
2) useMutation()
3) mutation.mutate(새로운 데이터)
5. src > Content.tsx (삭제,변경,조회)
import React from 'react';
import styled from 'styled-components';
import { Todo } from '../types/Todo';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { changeTodos, deleteTodos, getTodos } from '../axios/queryApi';
type Props = {
isDone: boolean;
};
function Content({ isDone }: Props) {
const { isLoading, isError, data } = useQuery('todos', getTodos);
const queryClient = useQueryClient();
const mutationDelete = useMutation(deleteTodos, {
onSuccess: () => {
queryClient.invalidateQueries('todos');
},
});
const mutationChange = useMutation(changeTodos, {
onSuccess: () => {
queryClient.invalidateQueries('todos');
},
});
if (isLoading) {
return <div>로딩중..</div>;
}
if (isError) {
return <div>오류가 발생했습니다</div>;
}
const removeHandler = async (e: React.MouseEvent<HTMLButtonElement>, id: string) => {
try {
mutationDelete.mutate(id);
} catch (error) {
console.log('삭제 오류', error);
}
};
const changeHandler = async (e: React.MouseEvent<HTMLButtonElement>, id: string, isDone: boolean) => {
try {
mutationChange.mutate({ id, isDone });
} catch (error) {
console.log('상태 업데이트 오류', error);
}
};
return (
<>
<StDiv> {isDone ? '✌️Done✌️' : '✍️Working'}</StDiv>
<StDivLayout>
{data
.filter((item: Todo) => item.isDone === isDone)
.map((todo: Todo) => {
return (
<StDivTodo key={todo.id}>
<h3>{todo.title}</h3>
<p>{todo.content}</p>
<StDivBtn>
<DeleteButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) => removeHandler(e, todo.id)}
>
삭제
</DeleteButton>
<StateButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) =>
changeHandler(e, todo.id, todo.isDone)
}
>
{isDone ? '취소' : '완료'}
</StateButton>
</StDivBtn>
</StDivTodo>
);
})}
</StDivLayout>
</>
);
}
export default Content;
1) useQuery()
2) useMutation
3) data.filter(타입설정) .map( 타입설정)
끝.
반응형
'TIL :: Today I Learned' 카테고리의 다른 글
next.js : 리액트를 위한 웹 프레임워크 정리 (1) | 2023.12.22 |
---|---|
Recoil : 리액트 전역상태관리 라이브러리 (1) | 2023.12.21 |
TypeScript : 투두리스트 만들기 (4단계 - Thunk + Axios ) (0) | 2023.12.17 |
TypeScript : 투두리스트 만들기 (3단계 - Json-server) (0) | 2023.12.16 |
TypeScript : 투두리스트 만들기 (2단계 - Redux Toolkit) (1) | 2023.12.15 |