การแสดงผลการทำงานของ thunk ในคอมโพเนนต์ใน Redux

ในบทเรียนที่แล้วเราได้ส่งคำขอ POST โดยใช้ thunk addProduct ทีนี้มาลอง แสดงผลการทำงานของมันในคอมโพเนนต์กัน

เปิดแอปพลิเคชันสินค้าของเราขึ้นมา และเปิด ไฟล์ NewProductForm.jsx เนื่องจากคอมโพเนนต์นี้ มีหน้าที่รับผิดชอบในการเพิ่มสินค้าใหม่ ลองดูที่บรรทัดการ import แทนที่การ import action productAdded ด้วย การ import thunk addProduct:

products/NewProductForm.jsximport { addProduct } from './productsSlice'

ทีนี้ เนื่องจากเราไม่ได้ติดตามสถานะ 'pending' ของคำขอใน slice ลองมาทำให้ ผู้ใช้สามารถกดปุ่มบันทึกสินค้าได้เพียงครั้งเดียว เพราะ เราไม่ต้องการคำขอที่ซ้ำกันแบบเดิม สำหรับสิ่งนี้ เราจะสร้าง local state เพิ่มอีกหนึ่ง:

products/NewProductForm.jsxconst [requestStatus, setRequestStatus] = useState('idle')

ต่อไป หลังจากตัวจัดการเหตุการณ์และก่อนฟังก์ชัน onSaveProductClick ให้เขียนโค้ดที่ ตรวจสอบว่าฟิลด์แบบฟอร์มทั้งหมดของเราถูกกรอกครบหรือไม่ และสถานะคำขออยู่ที่ 'idle' หรือไม่:

products/NewProductForm.jsxconst canBeSaved =
  [name, desc, price, amount, sellerId].every(Boolean) &&
  requestStatus === 'idle'

จากนั้นเราจะเปลี่ยนโค้ดสำหรับ onSaveProductClick ประการแรก นี่จะเป็นฟังก์ชันแบบอะซิงโครนัสและมันจะทำงาน, หากเงื่อนไขข้างต้นเป็นจริง:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {}
}

แม้ว่าเราไม่ได้ติดตามสถานะ 'rejected' ใน slice เรายังสามารถแสดงข้อผิดพลาดใน console ได้ โดยใช้ โครงสร้าง try-catch นอกจากนี้เราจะเพิ่ม finally ด้วย, เพื่อตั้งค่า local state กลับเป็น 'idle' หลังจากคำขอทำงานเสร็จ:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {
    try {
    } catch (err) {
      console.error('save product error: ', err)
    } finally {
      setRequestStatus('idle')
    }
  }
}

เราได้จัดการกับบล็อก catch และ finally แล้ว มาลอง เขียนโค้ดสำหรับบล็อก try กัน ที่นี่เราจะตั้งค่าสถานะท้องถิ่น เป็น 'in progress' จนกว่าเราจะได้รับ การตอบกลับใด ๆ จากการทำงานของ thunk, จากนั้นส่ง thunk addProduct ของเราไป ในการใช้ โครงสร้าง try-catch ตาม ประเภทของการตอบกลับจะช่วยเราได้โดยฟังก์ชัน RTK unwrap, ซึ่งมันเพิ่มเข้ามาใน promise ที่ส่งคืน จากนั้น หากคำขอสำเร็จ เราจะตั้งค่า local state กลับไปเป็นสถานะเริ่มต้น โค้ดทั้งหมดสำหรับ onSaveProductClick จะมีลักษณะดังนี้:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {
    try {
      setRequestStatus('in progress')
      await dispatch(
        addProduct({ name, desc, price, amount, seller: sellerId })).unwrap()
      setName('')
      setDesc('')
      setPrice(0)
      setAmount(0)
      setSellerId('')
    } catch (err) {
      console.error('save product error: ', err)
    } finally {
      setRequestStatus('idle')
    }
  }
}

มาเริ่มต้นแอปพลิเคชันของเราและลองเพิ่ม สินค้าใหม่กัน อย่างที่คุณเห็น ในกรณีที่คำขอสำเร็จ ฟิลด์จะถูกล้างและสินค้าใหม่จะถูกเพิ่มเข้าไป ในรายการสินค้า นอกจากนี้ลองดูในเบราว์เซอร์ ที่ Redux DevTools และลองสำรวจแท็บต่าง ๆ ของมัน, ดูที่ actions และวิธีที่ state ของคุณเปลี่ยนแปลง

Задание 1

เปิดแอปพลิเคชันนักเรียนของคุณ เปิดไฟล์ NewStudentForm.jsx ในนั้น เพิ่ม local state requestStatus อีกหนึ่ง, และตั้งค่าเริ่มต้นเป็น 'idle' หลังจากศึกษาบทเรียนแล้ว ให้สร้าง ตัวแปร canBeSaved โดยที่ ปุ่มบันทึกข้อมูลนักเรียนใหม่จะ ทำงาน/ไม่ทำงาน ขึ้นอยู่กับค่า requestStatus และความสมบูรณ์ของการกรอกฟิลด์

Задание 2

เขียนโค้ดแบบอะซิงโครนัสสำหรับ onSaveStudentClick, ซึ่งจะเปลี่ยนค่า requestStatus ตามสถานการณ์ ส่ง thunk addProduct พร้อมข้อมูลนักเรียนใหม่ ล้างฟิลด์ ในกรณีที่คำขอสำเร็จ และแสดง ข้อผิดพลาดใน console ในกรณีที่ล้มเหลว, ตามที่แสดงในบทเรียน ใช้ โครงสร้าง try-catch และฟังก์ชัน RTK unwrap สำหรับสิ่งนี้

Задание 3

เริ่มต้นแอปพลิเคชันของคุณ เพิ่มนักเรียนใหม่ และตรวจสอบให้แน่ใจว่าทุกอย่างทำงานได้