@Composable: มันคืออะไร คำอธิบายประกอบ Compose และขอบเขตการใช้งาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-06-27 เวลาอ่าน: 8 นาที

คำอธิบายประกอบ @Composable เป็นองค์ประกอบพื้นฐานของ Jetpack Compose ที่เปลี่ยนฟังก์ชัน Kotlin ทั่วไปให้เป็นบล็อกการสร้างส่วนติดต่อผู้ใช้แบบประกาศ หากไม่มีคำอธิบายประกอบนี้ จะไม่สามารถสร้างหน้าจอใดๆ ในการพัฒนา Android สมัยใหม่ได้ ตามข้อมูลของ Google Android Developers, 2026 กว่า 80% ของโปรเจกต์ Kotlin ใหม่ใช้ Compose ในการสร้าง UI และ @Composable เป็นคำอธิบายประกอบที่ใช้บ่อยที่สุดในระบบนิเวศ

ประเด็นสำคัญ

  • @Composable — คำอธิบายประกอบ Kotlin ที่อนุญาตให้ฟังก์ชันอธิบาย UI แบบประกาศ
  • ฟังก์ชัน Composable สามารถเรียกใช้เฉพาะฟังก์ชัน Composable อื่นๆ เท่านั้น โดยปฏิบัติตามบริบทของการประกอบ
  • การเริ่มต้นใหม่ ของฟังก์ชัน Composable เกิดขึ้นเมื่อพารามิเตอร์อินพุตหรือสถานะเปลี่ยนแปลง
  • ลำดับการเรียก ฟังก์ชัน Composable ไม่ได้รับการรับประกัน — Compose ปรับการสร้าง UI ใหม่ให้เหมาะสม
  • การตั้งชื่อ ฟังก์ชัน Composable เป็นไปตามกฎ PascalCase เช่นเดียวกับคอมโพเนนต์อื่นๆ ใน Compose

@Composable ใน Jetpack Compose คืออะไร

@Composable คือคำอธิบายประกอบของภาษา Kotlin ที่ทำเครื่องหมายฟังก์ชันว่ามีไว้สำหรับอธิบายส่วนติดต่อผู้ใช้ในเฟรมเวิร์ก Jetpack Compose เมื่อคอมไพเลอร์ Kotlin พบคำอธิบายประกอบนี้ มันจะสร้างโค้ดเพิ่มเติมที่ช่วยให้ฟังก์ชันทำงานในบริบทของการประกอบ — ระบบจัดการโครงสร้าง UI

คำอธิบายประกอบ @Composable ถูกนำเสนอโดย Google ในปี 2021 พร้อมกับเวอร์ชันเสถียรแรกของ Jetpack Compose 1.0 ก่อนที่จะปรากฏ การพัฒนาส่วนติดต่อ Android ดำเนินการผ่าน XML มาร์กอัปและระบบ View เท่านั้น @Composable เปลี่ยนแนวทางอย่างสิ้นเชิง: แทนที่จะอธิบาย UI ในไฟล์มาร์กอัปแยกต่างหาก นักพัฒนาจะเขียนส่วนติดต่อโดยตรงใน Kotlin

ความแตกต่างหลักระหว่าง @Composable และฟังก์ชัน Kotlin ทั่วไปคือความสามารถในการอ่านและตอบสนองต่อการเปลี่ยนแปลงสถานะ เมื่อตัวแปรที่ฟังก์ชัน Composable อ่านเปลี่ยนค่า ระบบจะกำหนดเวลาการเริ่มต้นใหม่ (การประกอบใหม่) ของฟังก์ชันนั้นโดยอัตโนมัติ ซึ่งช่วยให้นักพัฒนาไม่ต้องอัปเดต UI ด้วยตนเองผ่าน findViewById และ setText

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

วิธีประกาศฟังก์ชัน Composable

ในการประกาศฟังก์ชัน Composable เพียงเพิ่มคำอธิบายประกอบ @Composable หน้าคีย์เวิร์ด fun ฟังก์ชันต้องอยู่ในแพ็กเกจที่นำเข้าคำอธิบายประกอบจาก androidx.compose.runtime แนะนำให้เขียนชื่อฟังก์ชันด้วยตัวพิมพ์ใหญ่ — นี่คือธรรมเนียมที่ยอมรับอย่างกว้างขวางในชุมชน Compose ซึ่งแยกความแตกต่างระหว่างคอมโพเนนต์ UI กับฟังก์ชันทั่วไปด้วยสายตา

kotlin
import androidx.compose.runtime.Composable

@Composable
fun Greeting(name: String) {
    var count by remember { mutableStateOf(0) }
    Column {
        Text("สวัสดี, $name!")
        Button(onClick = { count++ }) {
            Text("คลิก $count ครั้ง")
        }
    }
}

พารามิเตอร์ของฟังก์ชัน Composable สามารถเป็นอะไรก็ได้ — ชนิดดั้งเดิม สตริง แลมบ์ดา และแม้แต่ฟังก์ชัน Composable อื่นๆ ที่ส่งผ่าน Slot API แนะนำ ให้ทำให้พารามิเตอร์ไม่เปลี่ยนรูป (val) เพื่อหลีกเลี่ยงผลข้างเคียงระหว่างการประกอบใหม่ ข้อมูลที่เปลี่ยนแปลงได้ทั้งหมดควรจัดการผ่านกลไกสถานะของ Compose

ฟังก์ชัน Composable ไม่สามารถคืนค่าใดๆ ได้ตามอำเภอใจเหมือนฟังก์ชันทั่วไป — งานเดียวของพวกเขาคือสร้างหรืออัปเดตส่วนหนึ่งของโครงสร้าง UI อย่างไรก็ตาม มีรูปแบบพิเศษเช่น State Hoisting ซึ่งฟังก์ชัน Compose รับสถานะและ callback ผ่านพารามิเตอร์ โดยคงความบริสุทธิ์และสามารถนำกลับมาใช้ใหม่ได้

กฎของฟังก์ชัน Composable ใน Kotlin

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

กฎข้อที่สองเกี่ยวกับลำดับการทำงาน Compose มีสิทธิ์เรียกใช้ฟังก์ชัน Composable ใน ลำดับใดก็ได้ ดังนั้นโค้ดในเนื้อหาของฟังก์ชันดังกล่าวต้องไม่ขึ้นอยู่กับลำดับการเรียกของฟังก์ชันข้างเคียง แต่ละฟังก์ชัน Composable ต้องพึ่งพาตนเองได้ในระดับตำแหน่งของมันในโครงสร้าง UI

กฎข้อที่สาม — ห้ามผลข้างเคียง ภายในเนื้อหาของฟังก์ชัน Composable การดำเนินการเช่นการเขียนฐานข้อมูล การส่งคำขอเครือข่าย หรือการแก้ไขตัวแปรภายนอกต้องทำภายในเอฟเฟกต์พิเศษเท่านั้น: LaunchedEffect, DisposableEffect หรือ SideEffect การละเมิดกฎนี้จะนำไปสู่พฤติกรรมที่คาดเดาไม่ได้ระหว่างการประกอบใหม่

กฎข้อที่สี่: ฟังก์ชัน Composable ต้องมีคุณสมบัติ idempotent การเรียกซ้ำด้วยอาร์กิวเมนต์เดียวกันควรสร้าง UI เดียวกัน ข้อกำหนดนี้จำเป็นสำหรับการทำงานที่ถูกต้องของการปรับแต่งการข้าม ซึ่ง Compose จะข้ามการวาดซ้ำของฟังก์ชันที่ข้อมูลอินพุตไม่เปลี่ยนแปลง

kotlin
// ถูกต้อง: ฟังก์ชัน Composable บริสุทธิ์ไม่มีผลข้างเคียง
@Composable
fun UserCard(user: User, onClick: () -> Unit) {
    Card(modifier = Modifier.clickable { onClick() }) {
        Text(text = user.name)
    }
}

// ผิด: ผลข้างเคียงภายในเนื้อหา
@Composable
fun WrongCard(userId: String) {
    // val result = viewModel.loadUser(userId)  // ไม่ได้รับอนุญาต
    Text("กำลังโฬหด...")
}

ตัวอย่างการใช้ @Composable

มาดูตัวอย่างการใช้งานจริงของการสร้างหน้าจอโปรไฟล์โดยใช้คำอธิบายประกอบ @Composable ที่นี่เราสาธิตการรวมหลายฟังก์ชัน Composable การทำงานกับสถานะและตัวปรับแต่ง — องค์ประกอบสำคัญของเลย์เอาต์ Compose ใดๆ

kotlin
@Composable
fun ProfileScreen(userId: String) {
    var isFollowed by remember { mutableStateOf(false) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        ProfileHeader(userId = userId)
        Spacer(modifier = Modifier.height(16.dp))
        StatsRow(posts = 42, followers = 1280)
        Spacer(modifier = Modifier.height(24.dp))
        FollowButton(
            isFollowed = isFollowed,
            onToggle = { isFollowed = !isFollowed }
        )
    }
}

@Composable
fun ProfileHeader(userId: String) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        AsyncImage(model = "https://example.com/avatars/$userId",
            contentDescription = "User avatar")
        Spacer(modifier = Modifier.width(12.dp))
        Text(text = "ผู้ใช้ #$userId", style = MaterialTheme.typography.headlineMedium)
    }
}

@Composable
fun StatsRow(posts: Int, followers: Int) {
    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
        StatItem("Posts", posts)
        StatItem("Followers", followers)
    }
}

@Composable
fun StatItem(label: String, value: Int) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "$value", style = MaterialTheme.typography.headlineSmall)
        Text(text = label, style = MaterialTheme.typography.bodySmall)
    }
}

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

ประเภทของฟังก์ชัน Composable และวัตถุประสงค์

ใน Jetpack Compose มี ฟังก์ชัน Composable หลักสามประเภท ประเภทแรก — คอนเทนเนอร์ (Row, Column, Box, LazyColumn) — กำหนดการจัดวางขององค์ประกอบลูก ประเภทที่สอง — องค์ประกอบการแสดงผล (Text, Image, Icon, Button) — เรนเดอร์คอมโพเนนต์ UI เฉพาะ ประเภทที่สาม — ฟังก์ชัน Composable ที่กำหนดเอง — รวมคอมโพเนนต์ในตัวเป็นบล็อกที่ใช้ซ้ำได้

คอนเทนเนอร์แตกต่างจากองค์ประกอบทั่วไปตรงที่รับ lambda content — พารามิเตอร์สุดท้ายชนิด @Composable () -> Unit กลไกนี้ช่วยให้สร้างโครงสร้าง UI ที่ซ้อนกันได้: แต่ละคอนเทนเนอร์สร้างการประกอบลูกที่มีบริบทและพื้นที่หน่วยความจำของตัวเอง

ฟังก์ชัน Composable ที่กำหนดเองแบ่งออกเป็นสองประเภทย่อย: สมาร์ท (smart) และ ธรรมดา (dumb) ฟังก์ชันสมาร์ทจัดการสถานะและตรรกะ — ประกอบด้วยการเรียก remember, LaunchedEffect และ API อื่นๆ ของ Compose ฟังก์ชันธรรมดารับข้อมูลทั้งหมดผ่านพารามิเตอร์และแสดงผลเท่านั้น การแยกคอมโพเนนต์สมาร์ทและธรรมดาช่วยปรับปรุงความสามารถในการทดสอบและการใช้โค้ดซ้ำ

ประเภทตัวอย่างวัตถุประสงค์
คอนเทนเนอร์Column, Row, Boxจัดการการจัดวางองค์ประกอบลูก
องค์ประกอบText, Image, Buttonแสดงเนื้อหาและจัดการอินพุต
กำหนดเองProfileCard, UserListรวมคอมโพเนนต์มาตรฐาน

@Composable และการใช้คอมโพเนนต์ซ้ำ

ข้อได้เปรียบหลักของคำอธิบายประกอบ @Composable คือความสามารถในการสร้างคอมโพเนนต์ UI ที่ใช้ซ้ำได้โดยไม่ต้องมีการสืบทอดและลำดับชั้นคลาสที่ซับซ้อน ต่างจากระบบ View ที่แต่ละองค์ประกอบที่กำหนดเองต้องสร้างคลาส Java พร้อมคอนสตรัคเตอร์ คอมโพเนนต์ Composable เป็นเพียงฟังก์ชัน Kotlin ที่มีพารามิเตอร์

เพื่อรับประกันการใช้ซ้ำ จะใช้รูปแบบ Slot API ซึ่งฟังก์ชัน Composable รับ lambda content สำหรับพื้นที่ต่างๆ ของเลย์เอาต์ ตัวอย่างเช่น คอมโพเนนต์ Card สามารถรับเนื้อหาแยกต่างหากสำหรับส่วนหัว ส่วนเนื้อหา และส่วนท้าย ทำให้มันใช้งานได้ทั่วไปกับทุกหน้าจอของแอปพลิเคชัน

ตัวปรับแต่ง (Modifier) มีบทบาทสำคัญในการใช้ซ้ำ: อนุญาตให้กำหนดค่าระยะห่าง ขนาด การคลิก และแอนิเมชันโดยไม่ต้องเปลี่ยนคอมโพเนนต์本身 ขอแนะนำให้ส่ง Modifier เป็นพารามิเตอร์ของฟังก์ชัน Composable ด้วยค่าเริ่มต้นเสมอ: Modifier = Modifier — นี่คือแนวทางปฏิบัติมาตรฐานที่นำมาใช้ในไลบรารีทางการของ Google

kotlin
@Composable
fun SectionCard(
    modifier: Modifier = Modifier,
    title: String,
    content: @Composable () -> Unit
) {
    Card(modifier = modifier) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(text = title, style = MaterialTheme.typography.titleMedium)
            Spacer(modifier = Modifier.height(8.dp))
            content()
        }
    }
}

ด้วย Slot API คอมโพเนนต์ SectionCard สามารถใช้บนหน้าจอต่างๆ ที่มีเนื้อหาต่างกัน — ฟอร์ม รายการ บล็อกข้อความ การรวมกัน ของตัวปรับแต่งและ Slot API ทำให้คอมโพเนนต์ Compose มีความยืดหยุ่นสูงโดยไม่สูญเสียความปลอดภัยของชนิดที่ Kotlin มอบให้

คำถามที่พบบ่อย

@Composable แตกต่างจากฟังก์ชัน Kotlin ทั่วไปอย่างไร

ฟังก์ชัน @Composable ทำงานในบริบทของการประกอบและสามารถอ่านสถานะ โดยเริ่มต้นใหม่โดยอัตโนมัติเมื่อมีการเปลี่ยนแปลง ฟังก์ชัน Kotlin ทั่วไปไม่มีสิทธิ์เข้าถึงกลไกการติดตามสถานะและไม่มีส่วนร่วมในการสร้างโครงสร้าง UI

สามารถเรียกฟังก์ชัน Composable จากฟังก์ชันปกติได้หรือไม่

ไม่ ฟังก์ชัน Composable สามารถเรียกได้จากฟังก์ชัน Composable อื่นเท่านั้น เนื่องจากต้องใช้บริบทการประกอบพิเศษ ในการรวมโค้ด Compose กับ Kotlin ปกติ ให้ใช้เมธอด setContent { } ใน Activity หรือ ComposeView ในระบบ View

ทำไมฟังก์ชัน Composable จึงเขียนด้วยตัวพิมพ์ใหญ่

นี่คือธรรมเนียมการตั้งชื่อที่นำมาใช้ในชุมชน Compose ตัวพิมพ์ใหญ่แยกความแตกต่างระหว่าง คอมโพเนนต์ UI กับฟังก์ชันทั่วไปด้วยสายตา ตามกฎการตั้งชื่อคลาส ไม่ใช่ข้อกำหนดของคอมไพเลอร์ แต่เป็นแนวทางปฏิบัติที่แนะนำในเอกสารของ Google

หน้าจอหนึ่งสามารถมีฟังก์ชัน Composable ได้กี่ฟังก์ชัน

ไม่มีข้อจำกัดเกี่ยวกับจำนวน ในทางปฏิบัติ หน้าจอขนาดใหญ่สามารถมี 50–100 ฟังก์ชัน Composable รวมถึงคอมโพเนนต์ในตัว (Text, Button) และที่กำหนดเอง Compose ปรับแต่งโครงสร้างฟังก์ชันและดำเนินการเฉพาะฟังก์ชันที่ข้อมูลอินพุตเปลี่ยนแปลง

ฟังก์ชัน Composable สามารถคืนค่าได้หรือไม่

โดยปกติฟังก์ชัน Composable คืนค่า Unit เนื่องจากงานของพวกเขาคือสร้าง UI อย่างไรก็ตาม มีฟังก์ชัน เฉพาะทาง เช่น remember และ derivedStateOf ที่ถูกทำเครื่องหมายด้วย @Composable และคืนค่า นี่เป็นข้อยกเว้น ไม่ใช่กฎ

สรุป

  • @Composable — คำอธิบายประกอบสำหรับการอธิบาย UI แบบประกาศใน Jetpack Compose
  • ฟังก์ชัน Composable ถูกเรียกภายในฟังก์ชัน Composable อื่นในบริบทพิเศษเท่านั้น
  • Idempotent — การทำงานซ้ำแต่ละครั้งด้วยอาร์กิวเมนต์เดียวกันจะสร้าง UI เดียวกัน
  • ผลข้างเคียง ต้องไม่เกิดขึ้นในเนื้อหาฟังก์ชัน — ผ่าน LaunchedEffect และ SideEffect เท่านั้น
  • Slot API และ Modifier รับประกันการใช้คอมโพเนนต์ซ้ำโดยไม่ต้องสืบทอด
  • ฟังก์ชันคอนเทนเนอร์ (Row, Column, LazyColumn) รับ lambda content สำหรับองค์ประกอบที่ซ้อนกัน
  • คำแนะนำ: ส่ง Modifier เป็นพารามิเตอร์ของทุกฟังก์ชัน Composable ที่กำหนดเองด้วยค่าเริ่มต้น

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม