Contents

ทำความเข้าใจการจัดการสถานะในแอปพลิเคชัน Svelte

การจัดการสถานะเป็นส่วนสำคัญของเว็บแอปพลิเคชันสมัยใหม่ทุกตัว กรอบงานการพัฒนาเว็บหลักๆ แต่ละเฟรม เช่น React และ Vue มีวิธีจัดการสถานะที่แตกต่างกัน

Svelte ไม่สามารถหลีกหนีจากความท้าทายในการจัดการรัฐได้ และห้องสมุดก็นำเสนอกลยุทธ์หลายประการในการแก้ไขปัญหานี้

การจัดการของรัฐคืออะไรและเหตุใดจึงสำคัญ?

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

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

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

การจัดการของรัฐใน Svelte

โดยพื้นฐานแล้ว เราอาจใช้เครื่องหมายเท่ากับ (’=’) ภายใน Svelte เพื่อวิเคราะห์และแก้ไขตัวแปรสถานะ ตามภาพประกอบ สมมติว่าเนื้อหาขององค์ประกอบ h1 ต้องการสะท้อนตัวแปรสถานะเฉพาะ เราสามารถใช้สิ่งนี้ได้ดังนี้:

 <script>
let count = 0;
</script>

<h1>
{count}
</h1>

<button on:click={()=>count=count \+ 1}> Increase Count </button>

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

ผ่าน GIPHY

การอัปเดตตัวแปรสถานะอาร์เรย์ใน Svelte

ให้เราตรวจสอบข้อมูลโค้ดที่ตามมาโดยละเอียด:

 <script>
  let todoList = [
    "Read my books",
    "Eat some foods",
    "Bath the dogs",
    "Take out the garbage",
  ];

  function removeLastItem() {
    todoList.pop();
  }
</script>

<ul>
  {#each todoList as item}
    <li>{item}</li>
  {/each}
</ul>

<button on:click={() => removeLastItem()}> Remove last item</button>

ส่วนของโค้ดที่ให้มาจะสร้างความสอดคล้องระหว่างตัวแปรสถานะ “todoList” และโครงสร้างข้อมูลอาร์เรย์ เมื่อคลิกปุ่ม “ลบรายการสุดท้าย” ระบบจะดำเนินการฟังก์ชัน “removeLastItem()” ซึ่งจะกำจัดองค์ประกอบล่าสุดภายในตัวแปร “todoList”

อันที่จริง เราควรรันโค้ดนี้ภายในเว็บเบราว์เซอร์และโต้ตอบกับโค้ดโดยคลิกที่องค์ประกอบที่ออกแบบมาเพื่อลบรายการสุดท้าย การเปลี่ยนแปลงจะไม่ปรากฏในรายการที่แสดง

ผ่าน GIPHY

เพื่อหลีกเลี่ยงปัญหาด้านประสิทธิภาพที่อาจเกิดขึ้นจากการใช้ตัวดำเนินการ “=” ร่วมกับวิธีการจัดการอาเรย์ เช่น “.pop()” ภายในบริบทของแอปพลิเคชัน Svelte เราสามารถใช้กลยุทธ์การแก้ปัญหาโดยการแสดงผลแบบวนซ้ำ โครงสร้างรายการทั้งหมดผ่านกระบวนการที่เรียกว่า"การมอบหมายใหม่"สิ่งนี้เกี่ยวข้องกับการอัปเดตการอ้างอิงของออบเจ็กต์ข้อมูลต้นฉบับให้ชี้กลับมาที่ตัวมันเอง ดังนั้นจึงแจ้งให้เฟรมเวิร์กประเมินใหม่และอัปเดตการนำเสนอตามสถานะที่แก้ไขของตัวแปรที่เกี่ยวข้อง

 function removeLastItem() {
  todoList.pop();
  // Assign the updated array to itself
  todoList = todoList;
 }

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

ผ่าน GIPHY

การจัดการรัฐด้วยร้านค้า Svelte

ใน Svelte ร้านค้าจะถูกนำมาใช้เพื่ออำนวยความสะดวกในการแบ่งปันสถานะระหว่างส่วนประกอบที่ไม่เชื่อมต่อผ่านระบบปฏิกิริยา โดยพื้นฐานแล้ว ร้านค้าคือออบเจ็กต์ที่สามารถสมัครรับข้อมูลได้โดยใช้วิธี"สมัครสมาชิก"ซึ่งช่วยให้ส่วนประกอบสามารถตรวจสอบการอัปเดตที่ทำกับข้อมูลได้ ในการสร้างร้านค้าแบบอ่านและเขียนที่ตรงไปตรงมา เราจะต้องนำเข้าฟังก์ชัน เขียนได้ จากโมดูล JavaScript svelte/store ดังที่แสดงด้านล่าง:

 import { writeable } from "svelte/store"

แน่นอน ลองจินตนาการสักครู่ว่ามีสคริปต์ store.js ซึ่งประกอบด้วยเนื้อหาต่อไปนี้:

 import { writable } from "svelte/store";

export const todoList = writable([
    "Read my books",
    "Eat some foods",
    "Bath the dogs",
    "Take out the garbage",
    "Water the flowers"
]);

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

 <script>
import { todoList } from "./store";
</script>

ในการเข้าถึงอินสแตนซ์เฉพาะของวัตถุภายในคลาสใน Python เราสามารถใช้เมธอด \_\_getitem\_\_ หรือ Subscription ได้ ซึ่งช่วยให้สามารถเรียกค้นและจัดการข้อมูลที่ต้องการได้โดยตรง โดยไม่ต้องผ่านระดับต่างๆ ของการซ้อนภายในลำดับชั้นของคลาส

 let list;

todoList.subscribe((items)=>{
    list = items;
})

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

 <ul>
  {#each list as item}
    <li>{item}</li>
  {/each}
</ul>

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

 todoList.update((items) => {
  items.pop();
  return items;
});

การสร้างร้านค้าแบบอ่านอย่างเดียวใน Svelte

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

 import { readable } from 'svelte/store';

export const todoList = readable([
    "Read my books",
    "Eat some foods",
    "Bath the dogs",
    "Take out the garbage",
    "Water the flowers"
]);

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

 function removeLastItem() {
  todoList.update((items) => {
    items.pop();
    return items;
  });
}

การใช้ร้านค้าด้วย Context API

Svelte จัดเตรียม Context API ซึ่งสามารถใช้งานได้โดยการนำเข้าฟังก์ชัน setContext จากโมดูล’svelte’ช่วยให้นักพัฒนาสามารถสร้างและจัดการค่าบริบทภายในแอปพลิเคชันของตนได้อย่างมีประสิทธิภาพมากขึ้น

 import {setContext} from "svelte"

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

 // Parent Component
<script>
let age = 42;
</script>

<ChildComponent age={age} />

การใช้ Context API ช่วยให้เกิดการสื่อสารที่มีประสิทธิภาพระหว่างส่วนประกอบต่างๆ ภายในแอปพลิเคชัน โดยข้ามข้อกำหนดในการส่งข้อมูลผ่านตัวแปรระดับกลาง กลไกที่เทียบเคียงได้จัดทำโดย React โดยใช้ hook useContext ในการเรนเดอร์ค่าบริบทที่โต้ตอบใน Svelte จำเป็นต้องส่งค่าที่จัดเก็บที่เกี่ยวข้องไปยังบริบท

ในองค์ประกอบหลัก เราอาจพบการแสดงโครงสร้างดังต่อไปนี้:

 <script>
  import { writable } from "svelte/store";
  import Component2 from "./Component2.svelte";
  import { setContext } from "svelte";

  let numberInStore = writable(42);
  setContext("age", numberInStore);
</script>

<ChildComponent />
<button on:click={() => $numberInStore\+\+}>Increment Number</button>

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

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

 <script>
  import { getContext } from "svelte";
  let userAge = getContext("age");
</script>

<h1>
    {$userAge}
</h1>

การจัดการสถานะใน Svelte กับ React

กระบวนการจัดการสถานะใน Svelte ได้รับการปรับปรุงให้มีประสิทธิภาพมากขึ้นเมื่อเปรียบเทียบกับเวอร์ชันอื่นใน React โดยไม่ต้องการอะไรมากไปกว่าการใช้เครื่องหมายเท่ากับ (=) สำหรับทั้งการกำหนดและการอัปเดตสถานะ สิ่งนี้แตกต่างไปจากเฟรมเวิร์กการพัฒนาเว็บ เช่น React ซึ่งจำเป็นต้องมีการใช้งานฟังก์ชันต่างๆ เช่น useState และ useReducer เพื่อจัดการกับความท้าทายในการจัดการสถานะขั้นพื้นฐาน

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