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

52 KiB

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

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

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

บทนำ

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

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

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

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

ความรู้พื้นฐานที่ต้องมี

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

การตั้งค่าที่จำเป็น:

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

การทดสอบสภาพแวดล้อมของคุณ:

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

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

สิ่งที่คำสั่งนี้ทำ:

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

การวินิจฉัยปัญหาสถานะปัจจุบัน

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

มาทำการทดลองง่าย ๆ ที่เผยให้เห็นความท้าทายในการจัดการสถานะ:

🧪 ลองทดสอบการวินิจฉัยนี้:

  1. เข้าสู่ระบบแอปธนาคารของคุณและไปที่แดชบอร์ด
  2. รีเฟรชหน้าเบราว์เซอร์
  3. สังเกตว่าเกิดอะไรขึ้นกับสถานะการเข้าสู่ระบบของคุณ

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

ปัญหาการใช้งานปัจจุบัน:

ตัวแปร account แบบง่ายจาก บทเรียนก่อนหน้า สร้างปัญหาสำคัญสามประการที่ส่งผลต่อทั้งประสบการณ์ผู้ใช้และการดูแลรักษาโค้ด:

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

ความท้าทายด้านสถาปัตยกรรม:

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

💡 เรากำลังพยายามทำอะไรที่นี่?

การจัดการสถานะ เป็นเรื่องของการแก้ปริศนาสองข้อพื้นฐาน:

  1. ข้อมูลของฉันอยู่ที่ไหน?: การติดตามว่ามีข้อมูลอะไรและมาจากไหน
  2. ทุกคนเข้าใจตรงกันหรือไม่?: การทำให้สิ่งที่ผู้ใช้เห็นตรงกับสิ่งที่เกิดขึ้นจริง

แผนการของเรา:

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

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

การทำความเข้าใจการไหลของข้อมูลนี้:

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

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

⚠️ หัวข้อขั้นสูง: เราจะไม่ครอบคลุมการอัปเดต UI อัตโนมัติที่เกิดจากการเปลี่ยนแปลงสถานะ เนื่องจากเกี่ยวข้องกับแนวคิด การเขียนโปรแกรมเชิงปฏิกิริยา ถือว่าเป็นขั้นตอนต่อไปที่ยอดเยี่ยมสำหรับการเรียนรู้ของคุณ!

งาน: รวมโครงสร้างสถานะ

มาเริ่มเปลี่ยนการจัดการสถานะที่กระจัดกระจายของเราให้เป็นระบบรวมศูนย์กัน ขั้นตอนแรกนี้เป็นการสร้างรากฐานสำหรับการปรับปรุงทั้งหมดที่จะตามมา

ขั้นตอนที่ 1: สร้างวัตถุสถานะรวมศูนย์

แทนที่การประกาศ account แบบง่าย:

let account = null;

ด้วยวัตถุสถานะที่มีโครงสร้าง:

let state = {
  account: null
};

เหตุผลที่การเปลี่ยนแปลงนี้สำคัญ:

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

ขั้นตอนที่ 2: อัปเดตรูปแบบการเข้าถึงสถานะ

อัปเดตฟังก์ชันของคุณให้ใช้โครงสร้างสถานะใหม่:

ในฟังก์ชัน register() และ login(), แทนที่:

account = ...

ด้วย:

state.account = ...

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

const account = state.account;

สิ่งที่การอัปเดตเหล่านี้ทำสำเร็จ:

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

💡 หมายเหตุ: การปรับโครงสร้างนี้ไม่ได้แก้ปัญหาของเราในทันที แต่สร้างรากฐานที่จำเป็นสำหรับการปรับปรุงที่ทรงพลังที่จะตามมา!

การดำเนินการอัปเดตสถานะที่ควบคุม

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

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

การจัดการสถานะที่ไม่เปลี่ยนแปลง:

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

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

ประโยชน์ของการจัดการสถานะที่ไม่เปลี่ยนแปลง:

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

การจัดการสถานะไม่เปลี่ยนแปลงใน JavaScript ด้วย Object.freeze():

JavaScript มี Object.freeze() เพื่อป้องกันการแก้ไขวัตถุ:

const immutableState = Object.freeze({ account: userData });
// Any attempt to modify immutableState will throw an error

การแยกย่อยสิ่งที่เกิดขึ้นที่นี่:

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

💡 เจาะลึก: เรียนรู้เกี่ยวกับความแตกต่างระหว่างวัตถุไม่เปลี่ยนแปลงแบบ ตื้น และ ลึก ใน เอกสาร MDN การเข้าใจความแตกต่างนี้เป็นสิ่งสำคัญสำหรับโครงสร้างสถานะที่ซับซ้อน

งาน

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

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

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

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

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

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

updateState('account', result);

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

updateState('account', data);

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

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

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

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

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

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

การดำเนินการคงข้อมูล

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

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

คำถามเชิงกลยุทธ์สำหรับการคงข้อมูล:

ก่อนดำเนินการคงข้อมูล ให้พิจารณาปัจจัยสำคัญเหล่านี้:

| คำถาม | บริบทแ

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

งาน: การจัดการข้อมูลแบบถาวรด้วย localStorage

เราจะมาทำการจัดการข้อมูลแบบถาวรเพื่อให้ผู้ใช้ยังคงล็อกอินอยู่จนกว่าพวกเขาจะออกจากระบบอย่างชัดเจน โดยเราจะใช้ localStorage ในการเก็บข้อมูลบัญชีระหว่างการใช้งานเบราว์เซอร์

ขั้นตอนที่ 1: กำหนดการตั้งค่าการจัดเก็บข้อมูล

const storageKey = 'savedAccount';

สิ่งที่ค่าคงที่นี้ให้:

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

ขั้นตอนที่ 2: เพิ่มการจัดการข้อมูลแบบถาวรอัตโนมัติ

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

localStorage.setItem(storageKey, JSON.stringify(state.account));

การอธิบายสิ่งที่เกิดขึ้น:

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

💡 ประโยชน์ด้านสถาปัตยกรรม: เนื่องจากเราได้รวมการอัปเดตสถานะทั้งหมดไว้ใน updateState() การเพิ่มการจัดการข้อมูลแบบถาวรจึงใช้เพียงบรรทัดเดียว ซึ่งแสดงให้เห็นถึงพลังของการตัดสินใจด้านสถาปัตยกรรมที่ดี!

ขั้นตอนที่ 3: คืนค่าข้อมูลเมื่อแอปพลิเคชันโหลด

สร้างฟังก์ชันเริ่มต้นเพื่อคืนค่าข้อมูลที่บันทึกไว้:

function init() {
  const savedAccount = localStorage.getItem(storageKey);
  if (savedAccount) {
    updateState('account', JSON.parse(savedAccount));
  }

  // Our previous initialization code
  window.onpopstate = () => updateRoute();
  updateRoute();
}

init();

การทำความเข้าใจกระบวนการเริ่มต้น:

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

ขั้นตอนที่ 4: ปรับปรุงเส้นทางเริ่มต้น

อัปเดตเส้นทางเริ่มต้นเพื่อใช้ประโยชน์จากการจัดการข้อมูลแบบถาวร:

ใน updateRoute() ให้แทนที่:

// Replace: return navigate('/login');
return navigate('/dashboard');

เหตุผลที่การเปลี่ยนแปลงนี้สมเหตุสมผล:

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

การทดสอบการใช้งานของคุณ:

  1. ล็อกอินเข้าสู่แอปธนาคารของคุณ
  2. รีเฟรชหน้าเบราว์เซอร์
  3. ตรวจสอบว่าคุณยังคงล็อกอินอยู่และอยู่ในหน้าแดชบอร์ด
  4. ปิดและเปิดเบราว์เซอร์ใหม่
  5. กลับไปยังแอปของคุณและยืนยันว่าคุณยังคงล็อกอินอยู่

🎉 ความสำเร็จปลดล็อก: คุณได้ทำการจัดการสถานะแบบถาวรสำเร็จแล้ว! แอปของคุณตอนนี้ทำงานเหมือนแอปพลิเคชันเว็บระดับมืออาชีพ

การปรับสมดุลระหว่างการจัดการข้อมูลแบบถาวรกับความสดใหม่ของข้อมูล

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

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

🧪 การค้นพบปัญหาความสดใหม่ของข้อมูล:

  1. ล็อกอินเข้าสู่แดชบอร์ดโดยใช้บัญชี test
  2. รันคำสั่งนี้ในเทอร์มินัลเพื่อจำลองการทำธุรกรรมจากแหล่งอื่น:
curl --request POST \
     --header "Content-Type: application/json" \
     --data "{ \"date\": \"2020-07-24\", \"object\": \"Bought book\", \"amount\": -20 }" \
     http://localhost:5000/api/accounts/test/transactions
  1. รีเฟรชหน้าแดชบอร์ดในเบราว์เซอร์
  2. สังเกตว่าคุณเห็นธุรกรรมใหม่หรือไม่

สิ่งที่การทดสอบนี้แสดงให้เห็น:

  • แสดง ว่า localStorage อาจกลายเป็น "ล้าสมัย" (ไม่ทันสมัย)
  • จำลอง สถานการณ์จริงที่ข้อมูลเปลี่ยนแปลงนอกแอปของคุณ
  • เผย ความตึงเครียดระหว่างการจัดการข้อมูลแบบถาวรและความสดใหม่ของข้อมูล

ความท้าทายของข้อมูลล้าสมัย:

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

กลยุทธ์การแก้ปัญหา:

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

งาน: การสร้างระบบรีเฟรชข้อมูล

เราจะสร้างระบบที่ดึงข้อมูลใหม่จากเซิร์ฟเวอร์โดยอัตโนมัติในขณะที่ยังคงรักษาข้อดีของการจัดการสถานะแบบถาวร

ขั้นตอนที่ 1: สร้างฟังก์ชันอัปเดตข้อมูลบัญชี

async function updateAccountData() {
  const account = state.account;
  if (!account) {
    return logout();
  }

  const data = await getAccount(account.user);
  if (data.error) {
    return logout();
  }

  updateState('account', data);
}

การทำความเข้าใจตรรกะของฟังก์ชันนี้:

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

ขั้นตอนที่ 2: สร้างฟังก์ชันรีเฟรชแดชบอร์ด

async function refresh() {
  await updateAccountData();
  updateDashboard();
}

สิ่งที่ฟังก์ชันรีเฟรชนี้ทำสำเร็จ:

  • ประสานงาน กระบวนการรีเฟรชข้อมูลและการอัปเดต UI
  • รอ ให้ข้อมูลใหม่โหลดก่อนอัปเดตการแสดงผล
  • รับรอง ว่าแดชบอร์ดแสดงข้อมูลที่ทันสมัยที่สุด
  • รักษา การแยกที่ชัดเจนระหว่างการจัดการข้อมูลและการอัปเดต UI

ขั้นตอนที่ 3: รวมเข้ากับระบบเส้นทาง

อัปเดตการกำหนดค่าเส้นทางของคุณเพื่อกระตุ้นการรีเฟรชโดยอัตโนมัติ:

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard', init: refresh }
};

วิธีการทำงานของการรวมนี้:

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

การทดสอบระบบรีเฟรชข้อมูลของคุณ:

  1. ล็อกอินเข้าสู่แอปธนาคารของคุณ
  2. รันคำสั่ง curl จากก่อนหน้านี้เพื่อสร้างธุรกรรมใหม่
  3. รีเฟรชหน้าแดชบอร์ดหรือไปยังหน้าอื่นแล้วกลับมา
  4. ตรวจสอบว่าธุรกรรมใหม่ปรากฏทันที

🎉 สมดุลที่สมบูรณ์แบบ: แอปของคุณตอนนี้รวมประสบการณ์การใช้งานที่ราบรื่นของสถานะถาวรเข้ากับความถูกต้องของข้อมูลเซิร์ฟเวอร์ที่สดใหม่!

ความท้าทายของ GitHub Copilot Agent 🚀

ใช้โหมด Agent เพื่อทำความท้าทายต่อไปนี้:

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

คำสั่ง: สร้างระบบการจัดการสถานะที่ปรับปรุงแล้วซึ่งรวมถึง: 1) อาร์เรย์ประวัติสถานะที่ติดตามสถานะก่อนหน้า, 2) ฟังก์ชันย้อนกลับและทำซ้ำที่สามารถย้อนกลับไปยังสถานะก่อนหน้า, 3) ปุ่ม UI สำหรับการย้อนกลับ/ทำซ้ำบนแดชบอร์ด, 4) ขีดจำกัดประวัติสูงสุด 10 สถานะเพื่อป้องกันปัญหาหน่วยความจำ, และ 5) การล้างประวัติอย่างเหมาะสมเมื่อผู้ใช้ออกจากระบบ รับรองว่าฟังก์ชันย้อนกลับ/ทำซ้ำทำงานร่วมกับการเปลี่ยนแปลงยอดคงเหลือบัญชีและยังคงอยู่หลังการรีเฟรชเบราว์เซอร์

เรียนรู้เพิ่มเติมเกี่ยวกับ โหมด Agent ที่นี่

🚀 ความท้าทาย: การปรับปรุงการจัดเก็บข้อมูล

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

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

การวิเคราะห์การปรับปรุง:

ประเมินการใช้งาน localStorage ปัจจุบันของคุณและพิจารณาคำถามเชิงกลยุทธ์เหล่านี้:

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

กลยุทธ์การใช้งาน:

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

การพิจารณาขั้นสูง:

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

ความท้าทายนี้จะช่วยให้คุณคิดเหมือนนักพัฒนามืออาชีพที่พิจารณาทั้งประสบการณ์ผู้ใช้และประสิทธิภาพของแอปพลิเคชัน ใช้เวลาในการทดลองกับวิธีการต่าง ๆ!

แบบทดสอบหลังการบรรยาย

แบบทดสอบหลังการบรรยาย

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

สร้างหน้าต่าง "เพิ่มธุรกรรม"

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

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


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