บทนำสู่ Thunks ใน Redux
ในบทที่แล้วเราได้จัดตั้งการทำงานของเซิร์ฟเวอร์ ฐานข้อมูล และไคลเอ็นต์เพื่อแลกเปลี่ยนข้อมูล ตอนนี้เราจำเป็นต้องสร้างสะพานเชื่อมขั้นสุดท้ายที่จะช่วยให้แอปพลิเคชัน Redux ที่จัดระบบแบบ 'ซิงโครนัส' ของเราสามารถทำงานร่วมกับไคลเอ็นต์แบบอะซิงโครนัสที่เราสร้างขึ้นในบทเรียนสุดท้ายของบทที่แล้ว เพื่อส่งคำขอและรับข้อมูลที่จำเป็นในคำตอบ
ดังที่เราจำได้จากบทเรียนแรก ๆ ของส่วนก่อนหน้า Redux ไม่รู้อะไรเกี่ยวกับการทำงานกับลอจิคแบบอะซิงโครนัส และสำหรับสิ่งนี้เราจะใช้ thunk middleware Middleware นี้อนุญาตให้ทำงานกับ actions ที่ส่งออก ใช้เมธอด dispatch และ getState ของ store ในโค้ด thunk ของเรา และช่วยให้เมธอด dispatch ทำงานได้ไม่เพียงกับออบเจ็กต์ JS ปกติเท่านั้น แต่ยังรวมถึงเอนทิตีเช่นฟังก์ชันและพรอมิสด้วย
โดยปกติแล้วฟังก์ชัน thunk จะถูกเรียกด้วยอาร์กิวเมนต์สองตัวคือ dispatch และ getState (หากจำเป็น) ซึ่งสามารถใช้ในเนื้อหาของฟังก์ชันนี้ได้ ด้วยมันคุณสามารถส่ง actions ปกติได้ นอกจากนี้ยังสามารถส่งผ่าน store.dispatch ได้ ตัวอย่างของฟังก์ชันดังกล่าวแสดงไว้ด้านล่าง:
const changeColorThunk = (dispatch, getState) => {
const colorBefore = getState()
console.log(`สีเดิม: ${colorBefore.color}`)
dispatch(changeColor())
const colorAfter = getState()
console.log(`สีใหม่: ${colorAfter.color}`)
}
store.dispatch(changeColorThunk)
ตอนนี้เรามาเปิดแอปพลิเคชันผลิตภัณฑ์ของเรา สิ่งแรกที่เราควรได้รับจากเซิร์ฟเวอร์เมื่อเริ่มแอปพลิเคชันคือรายการผลิตภัณฑ์ เนื่องจากโดยทั่วไปแล้ว thunks จะถูกเขียนในไฟล์สไลซ์ เราจะเปิดไฟล์ productsSlice.js
ข่าวดีก็คือเราไม่จำเป็นต้องยุ่งกับการติดตั้ง Redux Thunk เนื่องจากฟังก์ชัน configureStore จาก RTK จะทำสิ่งนี้ให้เราแล้ว ดังนั้นเราจะเพียงเพิ่ม createAsyncThunk ในการนำเข้าในไฟล์:
import { createSlice, nanoid, createAsyncThunk } from '@reduxjs/toolkit'
นอกจากนี้ยังเพิ่มไคลเอ็นต์ของเราในการนำเข้า:
import { client } from '../../api/client'
และตอนนี้ด้วย createAsyncThunk เราจะสร้าง thunk แรกของเราเพื่อดึงข้อมูลผลิตภัณฑ์ เราจะทำสิ่งนี้ทันทีหลังจากการประกาศออบเจ็กต์ initialState:
export const fetchProducts = createAsyncThunk()
พารามิเตอร์แรกของ createAsyncThunk จะรับสตริงสำหรับประเภทของ action ที่ถูกสร้างขึ้น และพารามิเตอร์ที่สองคือฟังก์ชันคอลแบ็กสำหรับ payload ซึ่งจะส่งคืนข้อมูลหรือพรอมิสที่มีข้อผิดพลาด (ดูไฟล์ client.js) ในโค้ดของฟังก์ชันเราเรียก client.get และส่งเส้นทางที่เราระบุบนเซิร์ฟเวอร์ (ดูพารามิเตอร์ที่รับของ http.get ใน server.js):
export const fetchProducts = createAsyncThunk(
'products/fetchProducts',
async () => {
const response = await client.get('/fakeServer/products')
return response.data
}
)
เปิดแอปพลิเคชันนักเรียนของคุณ เปิดไฟล์ studentsSlice.js ในนั้น นำเข้าฟังก์ชัน createAsyncThunk เพื่อสร้าง thunk และ client เพื่อส่งคำขอ API ไปยังเซิร์ฟเวอร์
ทันทีหลังจากการประกาศออบเจ็กต์ initialState ด้วย createAsyncThunk ให้สร้าง thunk fetchStudents เพื่อดึงรายชื่อนักเรียน ซึ่งจะส่งคำขอ GET ไปยังที่อยู่ /fakeServer/students ที่ระบุไว้ในไฟล์ server.js ของคุณ และส่งคืน response.data ตามที่แสดงในเนื้อหาบทเรียน เป็นพารามิเตอร์แรกสำหรับ createAsyncThunk ระบุสตริง students/fetchStudents สำหรับประเภท action