You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/th/7-bank-project/4-state-management/README.md

19 KiB

สร้างแอปธนาคาร ตอนที่ 4: แนวคิดการจัดการสถานะ

แบบทดสอบก่อนเรียน

แบบทดสอบก่อนเรียน

บทนำ

เมื่อแอปพลิเคชันเว็บเติบโตขึ้น การติดตามการไหลของข้อมูลทั้งหมดกลายเป็นเรื่องท้าทาย โค้ดใดที่ได้รับข้อมูล หน้าใดที่ใช้ข้อมูลนั้น ต้องอัปเดตเมื่อใดและที่ไหน...ง่ายมากที่จะจบลงด้วยโค้ดที่ยุ่งเหยิงและยากต่อการดูแลรักษา โดยเฉพาะอย่างยิ่งเมื่อคุณต้องแชร์ข้อมูลระหว่างหน้าต่าง ๆ ของแอป เช่น ข้อมูลผู้ใช้ แนวคิดของ การจัดการสถานะ มีอยู่ในโปรแกรมทุกประเภทมาโดยตลอด แต่เมื่อแอปเว็บมีความซับซ้อนมากขึ้นเรื่อย ๆ การจัดการสถานะจึงกลายเป็นจุดสำคัญที่ต้องพิจารณาในระหว่างการพัฒนา

ในส่วนสุดท้ายนี้ เราจะมาทบทวนแอปที่เราได้สร้างขึ้นเพื่อคิดใหม่เกี่ยวกับวิธีการจัดการสถานะ โดยสนับสนุนการรีเฟรชเบราว์เซอร์ในทุกจุด และทำให้ข้อมูลคงอยู่ในเซสชันของผู้ใช้

ความต้องการเบื้องต้น

คุณต้องทำส่วน การดึงข้อมูล ของแอปเว็บให้เสร็จสมบูรณ์สำหรับบทเรียนนี้ นอกจากนี้คุณยังต้องติดตั้ง Node.js และ เรียกใช้เซิร์ฟเวอร์ API ในเครื่องเพื่อจัดการข้อมูลบัญชี

คุณสามารถทดสอบว่าเซิร์ฟเวอร์ทำงานได้อย่างถูกต้องโดยการรันคำสั่งนี้ในเทอร์มินัล:

curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result

ทบทวนการจัดการสถานะ

ใน บทเรียนก่อนหน้า เราได้แนะนำแนวคิดพื้นฐานของสถานะในแอปของเราด้วยตัวแปร account แบบ global ซึ่งมีข้อมูลธนาคารของผู้ใช้ที่เข้าสู่ระบบอยู่ในปัจจุบัน อย่างไรก็ตาม การใช้งานปัจจุบันของเรามีข้อบกพร่อง ลองรีเฟรชหน้าเมื่อคุณอยู่ในแดชบอร์ด เกิดอะไรขึ้น?

มีปัญหา 3 ข้อในโค้ดปัจจุบัน:

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

เราสามารถอัปเดตโค้ดของเราเพื่อแก้ไขปัญหาเหล่านี้ทีละข้อ แต่จะสร้างการทำซ้ำโค้ดมากขึ้นและทำให้แอปซับซ้อนและยากต่อการดูแลรักษา หรือเราสามารถหยุดชั่วคราวและคิดกลยุทธ์ใหม่

ปัญหาอะไรที่เรากำลังพยายามแก้ไขจริง ๆ?

การจัดการสถานะ คือการหาวิธีที่ดีในการแก้ไขปัญหาเฉพาะสองข้อนี้:

  • จะทำให้การไหลของข้อมูลในแอปเข้าใจง่ายได้อย่างไร?
  • จะทำให้ข้อมูลสถานะสอดคล้องกับส่วนติดต่อผู้ใช้เสมอ (และในทางกลับกัน) ได้อย่างไร?

เมื่อคุณจัดการกับสิ่งเหล่านี้แล้ว ปัญหาอื่น ๆ ที่คุณอาจมีอาจได้รับการแก้ไขแล้วหรือกลายเป็นเรื่องง่ายขึ้นในการแก้ไข มีวิธีการมากมายในการแก้ไขปัญหาเหล่านี้ แต่เราจะใช้วิธีแก้ไขทั่วไปที่ประกอบด้วย การรวมศูนย์ข้อมูลและวิธีการเปลี่ยนแปลงข้อมูล การไหลของข้อมูลจะเป็นดังนี้:

แผนภาพแสดงการไหลของข้อมูลระหว่าง HTML, การกระทำของผู้ใช้ และสถานะ

เราจะไม่ครอบคลุมส่วนที่ข้อมูลกระตุ้นการอัปเดตมุมมองโดยอัตโนมัติ เนื่องจากเกี่ยวข้องกับแนวคิดขั้นสูงของ Reactive Programming ซึ่งเป็นหัวข้อที่ดีสำหรับการศึกษาต่อหากคุณต้องการเจาะลึก

มีไลบรารีมากมายที่มีวิธีการต่าง ๆ ในการจัดการสถานะ Redux เป็นตัวเลือกที่ได้รับความนิยม ลองดูแนวคิดและรูปแบบที่ใช้ เนื่องจากมักเป็นวิธีที่ดีในการเรียนรู้ปัญหาที่อาจเกิดขึ้นในแอปเว็บขนาดใหญ่และวิธีแก้ไข

งาน

เราจะเริ่มต้นด้วยการปรับปรุงโค้ดเล็กน้อย แทนที่การประกาศ account:

let account = null;

ด้วย:

let state = {
  account: null
};

แนวคิดคือการ รวมศูนย์ ข้อมูลแอปทั้งหมดในวัตถุสถานะเดียว เรามีเพียง account ในสถานะตอนนี้ ดังนั้นมันจึงไม่เปลี่ยนแปลงมากนัก แต่สร้างเส้นทางสำหรับการพัฒนาในอนาคต

เรายังต้องอัปเดตฟังก์ชันที่ใช้มัน ในฟังก์ชัน register() และ login() แทนที่ account = ... ด้วย state.account = ...;

ที่ด้านบนของฟังก์ชัน updateDashboard() เพิ่มบรรทัดนี้:

const account = state.account;

การปรับปรุงโค้ดนี้เองไม่ได้ทำให้เกิดการปรับปรุงมากนัก แต่แนวคิดคือการวางรากฐานสำหรับการเปลี่ยนแปลงต่อไป

ติดตามการเปลี่ยนแปลงข้อมูล

ตอนนี้เราได้วางวัตถุ state เพื่อเก็บข้อมูลของเราแล้ว ขั้นตอนต่อไปคือการรวมศูนย์การอัปเดต เป้าหมายคือทำให้ง่ายต่อการติดตามการเปลี่ยนแปลงใด ๆ และเมื่อเกิดขึ้น

เพื่อหลีกเลี่ยงการเปลี่ยนแปลงที่เกิดขึ้นกับวัตถุ state การพิจารณาให้มันเป็น immutable หรือไม่สามารถแก้ไขได้เลยก็เป็นแนวปฏิบัติที่ดี นอกจากนี้ยังหมายความว่าคุณต้องสร้างวัตถุสถานะใหม่หากคุณต้องการเปลี่ยนแปลงสิ่งใดในนั้น ด้วยวิธีนี้ คุณสร้างการป้องกันเกี่ยวกับ side effects ที่อาจไม่ต้องการ และเปิดโอกาสสำหรับคุณสมบัติใหม่ในแอปของคุณ เช่น การทำ undo/redo ในขณะเดียวกันก็ทำให้ง่ายต่อการดีบัก ตัวอย่างเช่น คุณสามารถบันทึกการเปลี่ยนแปลงทุกครั้งที่เกิดขึ้นกับสถานะและเก็บประวัติการเปลี่ยนแปลงเพื่อทำความเข้าใจแหล่งที่มาของบั๊ก

ใน JavaScript คุณสามารถใช้ Object.freeze() เพื่อสร้างเวอร์ชันที่ไม่สามารถแก้ไขได้ของวัตถุ หากคุณพยายามเปลี่ยนแปลงวัตถุที่ไม่สามารถแก้ไขได้ จะเกิดข้อยกเว้นขึ้น

คุณรู้ความแตกต่างระหว่างวัตถุ shallow และ deep immutable หรือไม่? คุณสามารถอ่านเกี่ยวกับมัน ที่นี่

งาน

มาสร้างฟังก์ชัน updateState() ใหม่:

function updateState(property, newData) {
  state = Object.freeze({
    ...state,
    [property]: newData
  });
}

ในฟังก์ชันนี้ เรากำลังสร้างวัตถุสถานะใหม่และคัดลอกข้อมูลจากสถานะก่อนหน้าโดยใช้ spread (...) operator จากนั้นเราจะเขียนทับคุณสมบัติหนึ่งของวัตถุสถานะด้วยข้อมูลใหม่โดยใช้ bracket notation [property] สำหรับการกำหนดค่า สุดท้ายเราล็อกวัตถุเพื่อป้องกันการแก้ไขโดยใช้ Object.freeze() ตอนนี้เรามีเพียงคุณสมบัติ account ที่เก็บไว้ในสถานะ แต่ด้วยวิธีนี้คุณสามารถเพิ่มคุณสมบัติได้มากเท่าที่คุณต้องการในสถานะ

เราจะอัปเดตการเริ่มต้น state เพื่อให้แน่ใจว่าสถานะเริ่มต้นถูกล็อกด้วย:

let state = Object.freeze({
  account: null
});

หลังจากนั้น อัปเดตฟังก์ชัน register โดยแทนที่การกำหนดค่า state.account = result; ด้วย:

updateState('account', result);

ทำเช่นเดียวกันกับฟังก์ชัน login โดยแทนที่ state.account = data; ด้วย:

updateState('account', data);

เราจะใช้โอกาสนี้แก้ไขปัญหาข้อมูลบัญชีที่ไม่ได้ถูกล้างเมื่อผู้ใช้คลิก ออกจากระบบ

สร้างฟังก์ชันใหม่ชื่อ logout():

function logout() {
  updateState('account', null);
  navigate('/login');
}

ใน updateDashboard() แทนที่การเปลี่ยนเส้นทาง return navigate('/login'); ด้วย return logout();

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

เคล็ดลับ: คุณสามารถดูการเปลี่ยนแปลงสถานะทั้งหมดได้โดยเพิ่ม console.log(state) ที่ด้านล่างของ updateState() และเปิดคอนโซลในเครื่องมือพัฒนาของเบราว์เซอร์ของคุณ

ทำให้สถานะคงอยู่

แอปเว็บส่วนใหญ่ต้องการเก็บข้อมูลเพื่อให้ทำงานได้อย่างถูกต้อง ข้อมูลสำคัญทั้งหมดมักจะถูกเก็บไว้ในฐานข้อมูลและเข้าถึงผ่านเซิร์ฟเวอร์ API เช่นเดียวกับข้อมูลบัญชีผู้ใช้ในกรณีของเรา แต่บางครั้งก็เป็นเรื่องน่าสนใจที่จะเก็บข้อมูลบางส่วนไว้ในแอปที่ทำงานในเบราว์เซอร์ของคุณ เพื่อประสบการณ์ผู้ใช้ที่ดีขึ้นหรือเพื่อปรับปรุงประสิทธิภาพการโหลด

เมื่อคุณต้องการเก็บข้อมูลในเบราว์เซอร์ มีคำถามสำคัญบางข้อที่คุณควรถามตัวเอง:

  • ข้อมูลนี้เป็นข้อมูลที่ละเอียดอ่อนหรือไม่? คุณควรหลีกเลี่ยงการเก็บข้อมูลที่ละเอียดอ่อนในฝั่งไคลเ แบบทดสอบหลังการบรรยาย

งานที่ได้รับมอบหมาย

พัฒนา "กล่องโต้ตอบเพิ่มธุรกรรม"

นี่คือตัวอย่างผลลัพธ์หลังจากทำงานที่ได้รับมอบหมายเสร็จ:

ภาพหน้าจอแสดงตัวอย่าง "กล่องโต้ตอบเพิ่มธุรกรรม"


ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator แม้ว่าเราจะพยายามให้การแปลมีความถูกต้อง แต่โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษามนุษย์ที่มีความเชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้