# Symfony Live Components และ UX 3.0: แอปพลิเคชันแบบ Reactive โดยไม่ต้องใช้ JavaScript ในปี 2026 > Symfony Live Components สร้างอินเทอร์เฟซแบบ reactive ด้วย PHP และ Twig โดยไม่ต้องใช้ JavaScript บทช่วยสอนเกี่ยวกับ LiveProp, LiveAction, form และ deferred loading - Published: 2026-05-10 - Updated: 2026-05-10 - Author: SharpSkill - Tags: symfony, live-components, ux-3, php, reactive - Reading time: 8 min --- Symfony Live Components นำเสนออินเทอร์เฟซผู้ใช้แบบ reactive และ real-time ทั้งหมดด้วย PHP และ Twig เปิดตัวในเดือนเมษายน 2026 [Symfony UX 3.0](https://symfony.com/blog/symfony-ux-3-0-0-released) ลบ deprecation ทั้งหมดจากเวอร์ชัน 2.x ยกระดับความต้องการขั้นต่ำเป็น PHP 8.4 และ Symfony 7.4 พร้อมทั้งตัดแพ็กเกจที่ล้าสมัยออกสี่ตัว — สร้าง UX toolkit ที่กระชับที่สุดเท่าที่เคยมีมา > **Live Components คืออะไร?** > > Live Components เปลี่ยน component Twig ใดก็ได้ให้เป็นเอลิเมนต์ที่มี state และโต้ตอบได้ ซึ่งถูก render ใหม่ฝั่ง server เมื่อผู้ใช้มีปฏิสัมพันธ์ — โดยไม่ต้องเขียน JavaScript data binding, action, validation และการจัดการ form ทั้งหมดเกิดขึ้นใน PHP ## การตั้งค่า Symfony UX 3.0 กับ Live Components การติดตั้งต้องใช้ Symfony 7.4+, PHP 8.4+ และ AssetMapper หรือ Webpack Encore สำหรับ asset ฝั่ง frontend ```bash # terminal composer require symfony/ux-live-component # With AssetMapper (recommended for Symfony 7.4+) php bin/console importmap:require @symfony/ux-live-component # Verify installation php bin/console debug:twig --filter=component ``` AssetMapper จัดการการส่งมอบ JavaScript โดยไม่ต้องใช้ Node.js, Webpack หรือขั้นตอน build ใดๆ Stimulus controller ที่ขับเคลื่อน Live Components จะถูกโหลดโดยอัตโนมัติ ## การสร้าง Component ค้นหาแบบ Reactive ด้วย LiveProp แถบค้นหาที่กรองผลลัพธ์ขณะที่ผู้ใช้พิมพ์ — ไม่ต้องใช้ JavaScript เลย แอตทริบิวต์ `#[LiveProp]` ทำเครื่องหมาย property ว่ามี state ซึ่งจะถูกรักษาไว้ระหว่างการ re-render ผ่าน token ที่เข้ารหัสและปลอดภัยสำหรับ URL ```php query) < 2) { return []; } return $this->productRepository->search( query: $this->query, category: $this->category === 'all' ? null : $this->category, limit: 20, ); } } ``` เทมเพลต Twig ที่สอดคล้องกันจะผูก input กับ property ด้วย `data-model` ```twig {# templates/components/ProductSearch.html.twig #}
{% for product in this.products %}

{{ product.name }}

{{ product.price|format_currency('EUR') }}
{% else %} {% if query|length >= 2 %}

No results for "{{ query }}".

{% endif %} {% endfor %}
``` Modifier `debounce(300)` รอ 300ms หลังจากการกดแป้นพิมพ์ครั้งสุดท้ายก่อนส่ง request แอตทริบิวต์ `key` บน item ของรายการช่วยให้ DOM morphing ทำงานอย่างมีประสิทธิภาพ — เฉพาะเอลิเมนต์ที่เปลี่ยนแปลงเท่านั้นที่ถูกอัปเดต > **URL Binding ด้วย LiveProp** > > การตั้งค่า `url: true` บน LiveProp จะซิงค์ค่า property กับ URL ของเบราว์เซอร์เป็น query parameter ผลการค้นหาที่สามารถ bookmark และแชร์ได้ — ด้วยแอตทริบิวต์เดียว ## การจัดการ Action ของผู้ใช้ด้วย LiveAction นอกเหนือจาก data binding แล้ว `#[LiveAction]` เปิดเผย method PHP เป็น action ที่สามารถเรียกใช้จาก frontend ได้ อาร์กิวเมนต์ถูกส่งผ่าน `#[LiveArg]` ```php cartService->add($productId, $quantity); $this->items = $this->cartService->getItems(); // Notify other components on the page $this->emit('cart:updated', [ 'count' => count($this->items), ]); } #[LiveAction] public function removeItem(#[LiveArg] int $itemId): void { $this->cartService->remove($itemId); $this->items = $this->cartService->getItems(); $this->emit('cart:updated', ['count' => count($this->items)]); } public function getTotal(): float { return array_sum(array_map( fn(CartItem $item) => $item->getPrice() * $item->getQuantity(), $this->items, )); } } ``` เทมเพลตเรียก action ด้วย helper `live_action()` หรือแอตทริบิวต์ `data-action` ```twig {# templates/components/ShoppingCart.html.twig #}

Cart ({{ items|length }})

{% for item in items %}
{{ item.name }} x{{ item.quantity }} {{ (item.price * item.quantity)|format_currency('EUR') }}
{% endfor %}
Total: {{ this.total|format_currency('EUR') }}
``` เมธอด `emit()` กระจาย event ไปยัง Live Components อื่นบนหน้า — ตัวอย่างเช่น component badge ตะกร้าสินค้าสามารถรับฟังด้วย `#[LiveListener('cart:updated')]` และอัปเดตจำนวนโดยไม่ต้องโหลดหน้าใหม่ทั้งหมด ## การตรวจสอบ Form แบบ Real-Time โดยไม่ต้องใช้ JavaScript Live Components ทำงานร่วมกับ [Symfony Forms](https://symfony.com/doc/current/forms.html) ได้โดยตรง `ComponentWithFormTrait` เชื่อมต่อสถานะ form, ข้อผิดพลาดจาก validation และการ submit เข้ากับ lifecycle ของ component ```php createForm(RegistrationType::class, $this->initialFormData ?? new User()); } #[LiveAction] public function save(EntityManagerInterface $em): mixed { // Submits + validates — re-renders with errors if invalid $this->submitForm(); $user = $this->getForm()->getData(); $em->persist($user); $em->flush(); $this->addFlash('success', 'Account created.'); return $this->redirectToRoute('app_login'); } } ``` ```twig {# templates/components/RegistrationForm.html.twig #}
{{ form_start(form, { attr: { 'data-action': 'live#action:prevent', 'data-live-action-param': 'save' } }) }} {{ form_row(form.email) }} {{ form_row(form.plainPassword, { label: 'Password' }) }} {{ form_row(form.fullName) }} {{ form_end(form) }}
``` ข้อผิดพลาดจาก validation จะแสดงแบบ inline เมื่อผู้ใช้เลื่อนระหว่างฟิลด์ — modifier `on(change)` บน `data-model` จะทริกเกอร์ re-render เมื่อ blur แสดงข้อความ constraint จาก Symfony Validator ทันที ## Deferred และ Lazy Loading เพื่อประสิทธิภาพ Component ที่หนัก — dashboard, กราฟวิเคราะห์, รายการยาว — ได้ประโยชน์จาก deferred rendering แทนที่จะบล็อกการโหลดหน้าแรก component จะแสดง placeholder และดึงเนื้อหาผ่าน AJAX หลังจากหน้าพร้อมแล้ว ```php analytics->getMetrics($this->period); } } ``` ```twig {# Parent page: load the dashboard after the page renders #} {# Or load when scrolled into view #} ``` มาโคร placeholder ภายในเทมเพลต component กำหนดสิ่งที่ผู้ใช้เห็นขณะที่เนื้อหาจริงกำลังโหลด ```twig {# templates/components/AnalyticsDashboard.html.twig #}

Analytics — {{ period }}

{% for metric in this.metrics %}
{{ metric.label }} {{ metric.value|number_format }}
{% endfor %}
{% macro placeholder(props) %}
{% endmacro %} ``` โหมด `loading="defer"` ส่ง AJAX request ทันทีเมื่อหน้าโหลด โหมด `loading="lazy"` ใช้ IntersectionObserver — request จะถูกส่งเมื่อ component เลื่อนเข้ามาใน viewport เท่านั้น ทั้งสองวิธีรักษาการตอบสนองของหน้าแรกให้เร็ว > **CSRF ถูกลบใน UX 3.0** > > Symfony UX 3.0 แทนที่ token CSRF ด้วยการป้องกัน same-origin/CORS สำหรับ Live Components อาร์กิวเมนต์ `csrf` บน `#[AsLiveComponent]` ไม่มีอีกต่อไป ต้องแน่ใจว่า server บังคับใช้นโยบาย same-origin ## การสื่อสารระหว่าง Component ด้วย Events Live Components สื่อสารผ่านระบบ event component ลูกส่ง event ออกไป component แม่ (หรือ sibling) รับฟังและตอบสนอง ```php count = $cartService->getItemCount(); } // Automatically re-renders when ShoppingCart emits 'cart:updated' #[LiveListener('cart:updated')] public function onCartUpdated(#[LiveArg] int $count): void { $this->count = $count; } } ``` รูปแบบนี้รักษาให้ component แยกจากกัน component ShoppingCart ไม่ได้อ้างอิง CartBadge โดยตรง — event bus จัดการการเชื่อมต่อ ## สิ่งที่เปลี่ยนแปลงใน Symfony UX 3.0 UX 3.0 เป็นรุ่นที่ทำความสะอาด แอปพลิเคชันที่ทำงานโดยไม่มีคำเตือน deprecation บน 2.x สามารถอัปเกรดได้โดยมีอุปสรรคน้อยที่สุด | การเปลี่ยนแปลง | ก่อน (2.x) | หลัง (3.0) | |---------------|------------|------------| | การป้องกัน CSRF | `csrf: true` บน `#[AsLiveComponent]` | Same-origin/CORS (อัตโนมัติ) | | ฟังก์ชัน Twig CVA | `cva()` | `html_cva()` จาก twig/html-extra 3.12+ | | Config defaults ของ component | ไม่บังคับ | `twig_component.defaults` บังคับ | | แพ็กเกจที่ถูกลบ | Swup, LazyImage, Typed, TogglePassword | ใช้ native API หรือ UX Toolkit | | ความต้องการ PHP | 8.1+ | 8.4+ | | ความต้องการ Symfony | 6.4+ | 7.4+ | [UX Toolkit](https://symfony.com/blog/symfonyux-2-32-0-released) ซึ่งเปิดตัวในช่วง 2.x มี component UI สำเร็จรูป (Button, Dialog, Card, Table, Pagination) ที่ styled ด้วย Shadcn UI หรือ Flowbite 4.0 — เติมเต็มช่องว่างที่แพ็กเกจที่ถูกลบทิ้งไว้ กำลังเตรียม[คำถามสัมภาษณ์งาน Symfony](/technologies/symfony/interview-questions/events-subscribers) อยู่หรือไม่? ความเข้าใจเกี่ยวกับ Live Components และระบบ event มีความเกี่ยวข้องมากขึ้นสำหรับตำแหน่งระดับ senior [คู่มือคำถามสัมภาษณ์ Symfony](/blog/symfony/symfony-interview-questions) ครอบคลุมหัวข้อพื้นฐานที่เหมาะสำหรับจับคู่กับความรู้เชิงปฏิบัตินี้ ## สรุป - Live Components ขจัดความจำเป็นในการใช้ framework JavaScript ในแอปพลิเคชัน Symfony ที่เน้น CRUD ส่วนใหญ่ data binding, action, validation และการจัดการ form ยังคงอยู่ใน PHP และ Twig - `#[LiveProp(writable: true, url: true)]` สร้างอินเทอร์เฟซที่มี state สามารถ bookmark และแชร์ได้ด้วยแอตทริบิวต์เดียว - Deferred และ lazy loading (`loading="defer"` / `loading="lazy"`) รักษาการโหลดหน้าแรกให้เร็วในขณะที่ component หนักถูก render แบบ asynchronous - UX 3.0 ยกเลิก token CSRF เพื่อใช้การป้องกัน same-origin/CORS — ความปลอดภัยที่เรียบง่ายกว่าด้วยชิ้นส่วนที่เคลื่อนไหวน้อยลง - ระบบ event (`emit` / `#[LiveListener]`) ช่วยให้การสื่อสารระหว่าง component แยกจากกันโดยไม่ต้องจัดการ state แบบ global - สำหรับ API ให้ผสม Live Components กับ [API Platform บน Symfony 7](/blog/symfony/symfony-7-api-platform-best-practices) สำหรับสถาปัตยกรรมที่เน้น backend --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/symfony/symfony-live-components-ux-3-reactive-apps-without-javascript