ทำความเข้าใจการจัดการสถานะในแอปพลิเคชัน 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 เหตุการณ์จะถูกแนบไปกับปุ่ม ซึ่งช่วยให้ผู้ใช้สามารถเพิ่มสถานะของ การนับ
ได้เมื่อพวกเขาคลิกที่ปุ่มดังกล่าว
การอัปเดตตัวแปรสถานะอาร์เรย์ใน 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”
อันที่จริง เราควรรันโค้ดนี้ภายในเว็บเบราว์เซอร์และโต้ตอบกับโค้ดโดยคลิกที่องค์ประกอบที่ออกแบบมาเพื่อลบรายการสุดท้าย การเปลี่ยนแปลงจะไม่ปรากฏในรายการที่แสดง
เพื่อหลีกเลี่ยงปัญหาด้านประสิทธิภาพที่อาจเกิดขึ้นจากการใช้ตัวดำเนินการ “=” ร่วมกับวิธีการจัดการอาเรย์ เช่น “.pop()” ภายในบริบทของแอปพลิเคชัน Svelte เราสามารถใช้กลยุทธ์การแก้ปัญหาโดยการแสดงผลแบบวนซ้ำ โครงสร้างรายการทั้งหมดผ่านกระบวนการที่เรียกว่า"การมอบหมายใหม่"สิ่งนี้เกี่ยวข้องกับการอัปเดตการอ้างอิงของออบเจ็กต์ข้อมูลต้นฉบับให้ชี้กลับมาที่ตัวมันเอง ดังนั้นจึงแจ้งให้เฟรมเวิร์กประเมินใหม่และอัปเดตการนำเสนอตามสถานะที่แก้ไขของตัวแปรที่เกี่ยวข้อง
function removeLastItem() {
todoList.pop();
// Assign the updated array to itself
todoList = todoList;
}
เมื่อรันโค้ดภายในเว็บเบราว์เซอร์ คาดว่าอาร์เรย์สถานะจะได้รับการอัปเดตตามที่ตั้งใจไว้เมื่อคลิกที่ปุ่มที่กำหนด
การจัดการรัฐด้วยร้านค้า 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