前一篇我們大致上了解了 API server 的運作與 todo 的格式,今天讓我們回歸主線,來使用 RTK query 整理我們的剛才的 todo APIs,在開始之前,先確定你的 server 是已經在運行的狀態,如果都準備好了就開始吧!
TodoList 應該是已經做到爛掉的東西了吧!大致的概念我就不詳述了,如果真的是超級新手的話可以 google 看看 todo list 教學,應該會多到不知道要選哪個來看,那麼我們就切入正題,大家可以搭配官方文件來使用,這部分會有點類似 context provider 的方式來提供需要使用這些 api 的 components 使用,這樣的做法有點類似 react-query 的做法,有經驗的朋友應該很快就能理解,這邊引入要注意,是接著 @reduxjs/toolkit/query/react
的路徑,所以不需要額外安裝什麼套件,那麼我們開始製作 Api。
首先我們於原本 src/featuers 的路徑下新增 api 的資料夾,然後進入該資料夾製作 todo api 的檔案來整合其 CRUD 的功能,這裡就提到一些基本的概念,我們打 API 的時候可以直接打,也可以將 url 做拆分再接續打,那這邊的概念就是後者,那麼我們的檔案會如下:
// scr/features/api/todoApi.ts
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"
// 做一份與 server 相同的 Todo 格式提供 component 使用
export interface Todo {
id: number;
text: string;
active: boolean;
done: boolean;
}
// 這裡 createApi 會自動將 endpoints 的 name 去組成相對應的 query
// 以 getAll 為例,使用時會組成 useGetAllQuery 的 function
export const todoApi = createApi({
reducerPath: 'todoApi',
baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:8080/'}),
tagTypes: ['Todos'],
endpoints: (builder) => ({
getAll: builder.query<Todo[], void>({
// 這裡的 query 代表接續 base 要傳入的值,providesTags 就是記錄一下對應的 tagType 詳細 https://redux-toolkit.js.org/rtk-query/usage/automated-refetchin
query: () => `todos`,
providesTags: [{type: 'Todos', id: 'LIST'}]
})
})
})
完成後我們先移動到 App 裏面,用 ApiProvider 去承接剛才定義完的 todoApi 如下:
// src/App.tsx
import { ApiProvider } from "@reduxjs/toolkit/dist/query/react"
import Counter from "./components/Counter"
import Point from "./components/Point"
import TodosList from "./components/TodosList"
import { todoApi } from "./features/api/todoApi"
function App() {
return (
<div className="container">
<h1>Typescript Demo</h1>
<Counter/>
<Point/>
<ApiProvider api={todoApi}>
<TodosList/>
</ApiProvider>
</div>
)
}
export default App
這樣處理之後,才能於我們的 TodosList component 拿到資料,那麼我們就接著處理 TodosList,先測試看看我們的 getAll 能不能正常運作拿到資料,如下:
// src/components/TodosList.tsx
import { todoApi } from "../features/api/todoApi"
const TodosList = () => {
// 使用剛才的 getAll query
const { data } = todoApi.useGetAllQuery();
return (
<div>{JSON.stringify(data)}</div>
)
}
export default TodosList
這時候畫面上應該會拿到對應的 JSON data,當然要確保你的 API Server 是正在運行的狀態,如果成功拿到資料的話我們來整理一下畫面,如下:
// src/components/TodosList.tsx
import { todoApi } from "../features/api/todoApi"
const TodosList = () => {
// 使用剛才的 getAll query
const { data } = todoApi.useGetAllQuery();
return (
<div className="card" style={{margin: '1rem 0'}}>
{data?.map((todo) => (
<div className="f-b-c" key={todo.id}>
<div>
<input type="checkbox" checked={todo.done} />
<span>{todo.text}</span>
</div>
<button>delete</button>
</div>
))}
</div>
)
}
export default TodosList
那麼,今天的內容就先到這裡,下一篇我們來試著串接其他的 request 實現新增、修改、刪除的功能。