[React Native] RTK-Query로 서버와 통신하기 (feat. Typescript)
Install
redux-toolkit
npm install @reduxjs/toolkit
TodoModel
interface TodoModel {
id: number;
title: string;
content: string;
}
Create API Slice
createApi와 fetchBaseQuery를 import 해줍니다.
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react';
저는 TodoList를 기반으로 아래와 같이 만들어 주겠습니다.
reducerPath: 스토어의 reducer로 지정할 Path의 이름
baseQuery: 기본으로 지정할 서버 URL
tagTypes: 자동으로 데이터가 패치되게 구별할 타입
endpoints: 엔드 포인트들
export const todoAPISlice = createApi({
reducerPath: 'todoAPI',
baseQuery: fetchBaseQuery({baseUrl: '서버URL'}),
tagTypes: ['Todos'],
endpoints: builder => ({
...
Get all todos
builder.query에 받아올 데이터 타입을 입력한 뒤,
query: () => endpoint를 입력해 줍니다.
providesTags는 invalidatesTags가 실행될 때 자동으로 패치될 쿼리를 나타냅니다.
(providesTags의 자세한 부분은 여기 를 참고해 주세요)
getAllTodos: builder.query<TodoModel[], String>({
query: () => '/allTodos',
providesTags: ['Todos'],
}),
add a todo
builder를 mutation으로 만들고 query의 파라미터에 새롭게 추가할 TodoModel을 받아옵니다.
그 다음 url에 endpoint를 입력해 주고, method는 POST, body에 파라미터의 todo를 넣어줍니다.
그리고 invalidatesTags에 태그를 입력해 주어 해당 쿼리가 실행되면 providesTags가 자동으로 패치되도록 해줍니다.
addTodo: builder.mutation({
query: (todo: TodoModel) => ({
url: '/addTodo',
method: 'POST',
body: todo,
}),
invalidatesTags: ['Todos'],
}),
edit a todo
addTodo와 거의 동일하지만 url의 파라미터 todo의 id를 넣어주고,
method는 PUT,
그리고 추가할 todo 모델을 body에 넣어줍니다.
addTodo와 마찬가지로 invalidatesTags를 추가해 데이터가 수정이 되면 자동으로 패치되도록 합니다.
editTodo: builder.mutation({
query: (todo: TodoModel) => ({
url: `/todo/${todo.id}`,
method: 'PUT',
body: todo,
}),
invalidatesTags: ['Todos'],
}),
delete a todo
url의 파라미터 todo의 id를 넣어주고,
method는 DELETE,
invalidatesTags를 추가해 데이터가 삭제가 되면 자동으로 패치되도록 합니다.
deleteTodo: builder.mutation({
query: (id: number) => ({
url: `/todo/${id}`,
method: 'DELETE',
}),
invalidatesTags: ['Todos'],
}),
마지막으로 todoAPISlice의 쿼리들을 export 해줍니다.
해당 endpoint에 맞게 쿼리 이름이 자동으로 지정됩니다.
ex) deleteTodo => useDeleteTodoMutation
export const {
useGetAllTodosQuery,
useAddTodoMutation,
useEditTodoMutation,
useDeleteTodoMutation,
} = todoAPISlice;
configureStore
configureStore에 위에서 지정해준 reducerPath를 todoAPISlice의 reducer로 지정해 줍니다.
그 다음 middleware를 todoAPISlice의 middleware로 지정해 줍니다.
const store = configureStore({
reducer: {
[todoAPISlice.reducerPath]: todoAPISlice.reducer,
},
middleware: getDefaultMiddleware =>
getDefaultMiddleware().concat(todoAPISlice.middleware),
});
APIProvider
APIProvider를 import 해주고,
import {ApiProvider} from '@reduxjs/toolkit/dist/query/react';
App을 APIProvider로 감싸 준뒤 api를 위에서 만들어준 todoAPISlice로 지정해 줍니다.
const App = () => {
return (
<ApiProvider api={todoAPISlice}>
<Provider store={store}>
<Home />
</Provider>
</ApiProvider>
);
};
Use apislice queries
가장 먼저 데이터를 받아올 useGetAllTodoQuery를 import 해줍니다.
import {useGetAllTodosQuery} from '../api/TodoAPISlice';
아래와 같이 data를 받아옵니다.
const {data} = useGetAllTodosQuery('');
FlatList에 해당 data를 연결해 주면 서버에 있는 데이터가 FlatList에 띄워지게 됩니다.
<FlatList
style={styles.list}
contentContainerStyle={{paddingBottom: 50}}
data={data}
...
추가나 수정도 똑같이 import 해주고
import {useAddTodoMutation} from '../api/TodoAPISlice';
import {useEditTodoMutation} from '../api/TodoAPISlice';
아래와 같이 액션을 만들어 준 뒤
const [addTodo] = useAddTodoMutation();
const [editTodo] = useEditTodoMutation();
todo를 담아 실행해 주면
addTodo(todo);
editTodo(todo);
원하는 todo가 추가되고 수정되게 됩니다.