wire:key คือ “ป้ายชื่อ” ที่เราติดให้กับ Element ใน Loop (เช่น foreach) เพื่อให้ Livewire สามารถติดตามและจัดการ Element แต่ละตัวได้อย่างถูกต้องแม่นยำเมื่อมีการเปลี่ยนแปลงข้อมูลใน Array ครับ
พูดง่ายๆ ก็คือ มันช่วยแก้ปัญหา “ความสับสน” ของ Livewire เมื่อเราทำการ เพิ่ม, ลบ, หรือสลับตำแหน่ง ของข้อมูลใน Array ที่แสดงผลบนหน้าเว็บครับ
🤔 ปัญหาคืออะไรถ้าไม่ใช้ wire:key?
ลองนึกภาพตามนะครับ เมื่อเรามีรายการ (list) ของข้อมูลที่แสดงผลด้วย foreach แล้วเราลบรายการใดรายการหนึ่งตรงกลางออกไป ถ้าไม่มี wire:key Livewire จะไม่รู้ว่า Element ไหนคืออันไหนกันแน่ มันอาจจะทำการ “อัปเดต” ข้อมูลใน Element ที่อยู่ท้ายๆ แทนที่จะ “ลบ” Element ที่ถูกต้องจริงๆ ซึ่งอาจทำให้เกิดข้อผิดพลาดในการแสดงผล, ข้อมูลใน input เพี้ยน, หรือ JavaScript ทำงานผิดพลาดได้
✅ wire:key เข้ามาช่วยได้อย่างไร?
เมื่อเราใส่ wire:key ให้กับ Element หลักใน Loop โดยใช้ค่าที่มีเอกลักษณ์ไม่ซ้ำกัน (unique) เช่น ID ของข้อมูล Livewire จะใช้ “ป้ายชื่อ” นี้ในการติดตาม Element แต่ละตัว
- เมื่อมีการลบ: Livewire จะรู้ทันทีว่าต้องลบ Element ที่มี
keyตรงกับข้อมูลที่ถูกลบไปจริงๆ - เมื่อมีการเพิ่ม: Livewire จะสร้าง Element ใหม่พร้อม
keyใหม่ - เมื่อมีการสลับตำแหน่ง: Livewire จะย้ายตำแหน่ง Element ตาม
keyได้อย่างถูกต้อง โดยไม่ไปยุ่งกับ state ภายในของ Element อื่นๆ
Custom Gem
แน่นอนครับ มาทำความเข้าใจ wire:key ใน Livewire 3 กันแบบง่ายๆ พร้อมตัวอย่างที่เห็นภาพชัดเจนครับ
wire:key คือ “ป้ายชื่อ” ที่เราติดให้กับ Element ใน Loop (เช่น foreach) เพื่อให้ Livewire สามารถติดตามและจัดการ Element แต่ละตัวได้อย่างถูกต้องแม่นยำเมื่อมีการเปลี่ยนแปลงข้อมูลใน Array ครับ
พูดง่ายๆ ก็คือ มันช่วยแก้ปัญหา “ความสับสน” ของ Livewire เมื่อเราทำการ เพิ่ม, ลบ, หรือสลับตำแหน่ง ของข้อมูลใน Array ที่แสดงผลบนหน้าเว็บครับ
🤔 ปัญหาคืออะไรถ้าไม่ใช้ wire:key?
ลองนึกภาพตามนะครับ เมื่อเรามีรายการ (list) ของข้อมูลที่แสดงผลด้วย foreach แล้วเราลบรายการใดรายการหนึ่งตรงกลางออกไป ถ้าไม่มี wire:key Livewire จะไม่รู้ว่า Element ไหนคืออันไหนกันแน่ มันอาจจะทำการ “อัปเดต” ข้อมูลใน Element ที่อยู่ท้ายๆ แทนที่จะ “ลบ” Element ที่ถูกต้องจริงๆ ซึ่งอาจทำให้เกิดข้อผิดพลาดในการแสดงผล, ข้อมูลใน input เพี้ยน, หรือ JavaScript ทำงานผิดพลาดได้
✅ wire:key เข้ามาช่วยได้อย่างไร?
เมื่อเราใส่ wire:key ให้กับ Element หลักใน Loop โดยใช้ค่าที่มีเอกลักษณ์ไม่ซ้ำกัน (unique) เช่น ID ของข้อมูล Livewire จะใช้ “ป้ายชื่อ” นี้ในการติดตาม Element แต่ละตัว
- เมื่อมีการลบ: Livewire จะรู้ทันทีว่าต้องลบ Element ที่มี
keyตรงกับข้อมูลที่ถูกลบไปจริงๆ - เมื่อมีการเพิ่ม: Livewire จะสร้าง Element ใหม่พร้อม
keyใหม่ - เมื่อมีการสลับตำแหน่ง: Livewire จะย้ายตำแหน่ง Element ตาม
keyได้อย่างถูกต้อง โดยไม่ไปยุ่งกับ state ภายในของ Element อื่นๆ
💡 ตัวอย่างการใช้งาน wire:key
สมมติว่าเรากำลังสร้าง Component สำหรับจัดการรายการสินค้า (Products)
ไฟล์ Component: app/Livewire/ProductList.php
<?php
namespace App\Livewire;
use App\Models\Product;
use Livewire\Component;
class ProductList extends Component
{
public $products;
public function mount()
{
$this->products = Product::all();
}
public function removeProduct($productId)
{
// กรองเอาสินค้าที่ต้องการลบออกไปจาก Collection
$this->products = $this->products->filter(function ($product) use ($productId) {
return $product->id != $productId;
});
}
public function render()
{
return view('livewire.product-list');
}
}
ไฟล์ View: resources/views/livewire/product-list.blade.php
ในตัวอย่างนี้ เราจะใช้ div เป็น Element หลักของแต่ละรายการใน loop และเราจะใส่ wire:key เข้าไปที่ div นี้ โดยใช้ product->id ซึ่งเป็นค่าที่ไม่ซ้ำกันแน่นอน
<div>
<h2>รายการสินค้า</h2>
<ul>
@foreach ($products as $product)
{{--
ใช้ wire:key ตรงนี้!
เพื่อให้ Livewire รู้ว่า list item นี้เป็นของ Product ID ไหน
--}}
<li wire:key="{{ $product->id }}">
<span>{{ $product->name }}</span>
<button wire:click="removeProduct({{ $product->id }})">ลบ</button>
</li>
@endforeach
</ul>
</div>
🚀 ผลลัพธ์ที่ได้
เมื่อคุณคลิกปุ่ม “ลบ” ของสินค้าชิ้นใดชิ้นหนึ่ง:
- Method
removeProduct()จะทำงาน และลบข้อมูลสินค้าออกจาก$productsCollection - Livewire จะทำการ re-render เฉพาะส่วนของรายการนี้
- ด้วย
wire:key="{{ $product->id }}"ที่เราใส่ไว้ Livewire จะรู้ทันทีว่าต้อง ลบ<li>ที่มีkeyตรงกับ ID ของสินค้าที่ถูกลบ ออกจากหน้า DOM อย่างถูกต้องแม่นยำ ทำให้การแสดงผลไม่ผิดเพี้ยนและทำงานได้อย่างราบรื่น
สรุปและคำแนะนำ ✨
- ควรใช้
wire:keyเสมอ เมื่อมีการใช้ loop (@foreach) ใน Livewire เพื่อแสดงผลข้อมูลแบบไดนามิก - ค่าที่นำมาใส่ใน
wire:keyต้องเป็นค่าที่ไม่ซ้ำกัน (unique) ภายใน loop นั้นๆ เช่นidของ Model หรือindexของ array ก็ได้ (แต่idจะปลอดภัยกว่าถ้ามีการสลับตำแหน่ง) - การใช้
wire:keyเป็น Best Practice ที่ช่วยป้องกันบั๊กแปลกๆ และทำให้ Component ของคุณทำงานได้อย่างมีประสิทธิภาพและเสถียรภาพสูงสุดครับ