Pressable — คืออะไร การจัดการกดใน React Native

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

Pressable เป็นคอมโพเนนท์ React Native ที่ทันสมัยสำหรับจัดการการสัมผัส แทนที่ TouchableHighlight, TouchableOpacity และ TouchableWithoutFeedback แบบเก่า Pressable มี API แบบรวมศูนย์พร้อมการตรวจจับสถานะ pressed, hovered และ focused คอมโพเนนท์นี้เปิดตัวใน React Native 0.63 และ Meta แนะนำให้ใช้ในโปรเจกต์ใหม่ทั้งหมด เรียนรู้เพิ่มเติมใน เอกสารของ Meta

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

  • Pressable — คอมโพเนนท์จัดการสัมผัสอเนกประสงค์ที่รองรับสถานะ pressed, hovered และ focused
  • API ประกอบด้วย callback onPress, onLongPress, onPressIn, onPressOut และฟังก์ชันจัดแต่งสไตล์ตามสถานะ
  • hitSlop ขยายพื้นที่สัมผัสเกินขอบเขตที่มองเห็นของคอมโพเนนท์เพื่อปรับปรุง UX
  • การแทนที่ Touchable — Pressable รวม API ของคอมโพเนนท์ Touchable ทั้งหมดเป็นอินเทอร์เฟซที่ยืดหยุ่นเดียว
  • การเข้าถึง — คอมโพเนนท์รองรับบทบาท ARIA และจัดการ VoiceOver และ TalkBack โดยอัตโนมัติ

Pressable คืออะไร?

Pressable เป็นคอมโพเนนท์ React Native ที่ให้อินเทอร์เฟซแบบรวมศูนย์สำหรับจัดการการสัมผัสทุกประเภท แตกต่างจากคอมโพเนนท์ Touchable สามแบบที่แตกต่างกัน (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback) Pressable แทนที่ทั้งหมดด้วยระบบสถานะและสไตล์ที่ยืดหยุ่นเดียว

คอมโพเนนท์นี้เปิดตัวใน React Native 0.63 (กันยายน 2020) ตามข้อมูลของ Meta (2026) 70% ของโปรเจกต์ React Native ใหม่ใช้ Pressable แทนคอมโพเนนท์ Touchable Pressable แก้ปัญหาหลักของ Touchable — API ที่กระจัดกระจายและความจำเป็นในการสลับระหว่างคอมโพเนนท์เพื่อเอฟเฟกต์ต่าง ๆ

ปรัชญาของ Pressable

ต่างจาก TouchableOpacity ที่เอฟเฟกต์การกดถูกกำหนดไว้ตายตัว (การเปลี่ยนความโปร่งใส) Pressable มีฟังก์ชันที่รับสถานะปัจจุบัน นักพัฒนาตัดสินใจว่าจะตอบสนองต่อการกดด้วยภาพอย่างไร: เปลี่ยนสี ขนาด เงา หรือการรวมกันของเอฟเฟกต์ ซึ่งให้การควบคุม UX อย่างเต็มที่

สถานะ Pressable: pressed, hovered, focused

Pressable กำหนดสถานะการโต้ตอบสามสถานะ: pressed (นิ้วบนหน้าจอ), hovered (เคอร์เซอร์เหนือองค์ประกอบบน Web/TV), focused (องค์ประกอบที่โฟกัสแป้นพิมพ์) แต่ละสถานะจะเรียก callback ที่เกี่ยวข้องและส่งต่อไปยังฟังก์ชันสไตล์และฟังก์ชันเรนเดอร์ลูก

สถานะเงื่อนไขการตอบสนองทั่วไป
pressedนิ้วบนหน้าจอหรือคลิกกดค้างการเปลี่ยนความโปร่งใส ขนาด หรือสีพื้นหลัง
hoveredเคอร์เซอร์เหนือองค์ประกอบ (Web, TV)การเน้น เงา ขีดเส้นใต้
focusedองค์ประกอบที่โฟกัสแป้นพิมพ์โครงร่าง เส้นขอบ การเปลี่ยนสี

สำคัญ: hovered และ focused ทำงานบนแพลตฟอร์มที่รองรับพอยน์เตอร์เท่านั้น (Web, Android TV, Apple TV) บนอุปกรณ์มือถือมีเฉพาะ pressed เท่านั้นที่ใช้งานได้ สำหรับแอปพลิเคชันข้ามแพลตฟอร์ม ให้ออกแบบการตอบสนองด้วยภาพโดยคำนึงถึงข้อจำกัดนี้

js
<Pressable
  style={({ pressed }) => [
    styles.button,
    pressed && styles.buttonPressed,
  ]}
  onPress={handlePress}>
  {({ pressed }) => (
    <Text style={pressed ? styles.textPressed : styles.text}>
      {pressed ? 'Release' : 'Press'}
    </Text>
  )}
</Pressable>

API และ callback ของ Pressable

Pressable API ประกอบด้วย callback หลักสี่ตัว: onPress (กดเต็มที่แล้วปล่อย), onLongPress (กดค้าง), onPressIn (เริ่มสัมผัส) และ onPressOut (สิ้นสุดสัมผัส) การรวมกันของ onPressIn และ onPressOut ช่วยให้สร้างแอนิเมชันแบบกำหนดเองได้

props เพิ่มเติม: delayLongPress (หน่วงเวลาการกดค้าง ค่าเริ่มต้น 500 ms), pressRetentionOffset (พื้นที่ที่เกินกว่านั้นการกดจะถูกยกเลิก), android_ripple (เอฟเฟกต์ ripple บน Android) หมายเหตุ: Ripple ทำงานบน Android 5+ เท่านั้น

js
<Pressable
  onPress={() => console.log('กด')}
  onLongPress={() => console.log('กดค้าง')}
  onPressIn={() => console.log('นิ้วลง')}
  onPressOut={() => console.log('นิ้วขึ้น')}
  delayLongPress={300}
  android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
  style={styles.button}>
  <Text>Press me</Text>
</Pressable>

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

hitSlop: การขยายพื้นที่สัมผัส

hitSlop คือ prop ของ Pressable ที่ขยายพื้นที่สัมผัสเกินขอบเขตที่มองเห็นของคอมโพเนนท์ ซึ่งสำคัญสำหรับองค์ประกอบขนาดเล็ก: ไอคอน, ช่องทำเครื่องหมาย, ปุ่มตัวเลือก Apple HIG แนะนำขนาดเป้าหมายสัมผัสขั้นต่ำ 44×44 จุด hitSlop ช่วยให้ปฏิบัติตามข้อกำหนดนี้โดยไม่เปลี่ยนขนาดที่มองเห็น

hitSlop รับออบเจ็กต์ { top, bottom, left, right } หรือตัวเลขเดียวสำหรับทุกด้าน ค่าจะถูกระบุเป็นพิกเซลเชิงตรรกะ (dp/pt) สำหรับไอคอน 24×24 แนะนำให้ใช้ hitSlop อย่างน้อย 10–12 ในแต่ละด้านเพื่อให้ได้เป้าหมายสัมผัส 44×44

js
<Pressable
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
  onPress={handleIconPress}
  style={styles.iconButton}>
  <Icon name="star" size={24} />
</Pressable>

pressRetentionOffset — ตรงข้ามกับ hitSlop: กำหนดพื้นที่ที่ผู้ใช้สามารถออกนอกขอบเขตคอมโพเนนท์ได้โดยไม่ยกเลิกการกด ค่าเริ่มต้นเท่ากับ hitSlop หากคุณต้องการให้การกดคงอยู่เมื่อออกนอกขอบเขต ให้เพิ่ม pressRetentionOffset

Pressable เทียบกับ Touchable: เมื่อใดควรเปลี่ยน

Pressable เทียบกับ Touchable — คำถามสำคัญเมื่อเลือกคอมโพเนนท์สำหรับจัดการการสัมผัส TouchableOpacity, TouchableHighlight และ TouchableWithoutFeedback เป็นคอมโพเนนท์เก่าที่จะไม่ถูกลบออก แต่จะไม่ได้รับฟีเจอร์ใหม่ Meta แนะนำ Pressable สำหรับโปรเจกต์ใหม่

ข้อได้เปรียบหลักของ Pressable: API แบบรวมศูนย์สำหรับเอฟเฟกต์ทุกประเภท การเข้าถึงสถานะ pressed สำหรับจัดแต่งสไตล์แบบกำหนดเอง การรองรับสถานะ hovered/focused, hitSlop และ pressRetentionOffset, callback onLongPress โดยไม่ต้องกำหนดค่าเพิ่มเติม TouchableOpacity เหมาะสำหรับการเปลี่ยนความโปร่งใสอย่างง่ายเท่านั้น

สถานการณ์TouchablePressable
กดธรรมดาTouchableOpacityPressable + opacity ใน style
เน้นพื้นหลังTouchableHighlightPressable + backgroundColor
ไม่มีเอฟเฟกต์ภาพTouchableWithoutFeedbackPressable ที่มี style ว่าง
กดค้างonLongPress บน Touchable ใด ๆonLongPress บน Pressable
แอนิเมชันกำหนดเองAnimated + onPressIn/OutPressable + useAnimatedStyle
Ripple บน AndroidTouchableNativeFeedbackPressable + android_ripple

ตัวอย่างการใช้งาน Pressable

Pressable ช่วยให้สร้างองค์ประกอบโต้ตอบที่ซับซ้อนด้วยโค้ดน้อยที่สุด ด้านล่างคือตัวอย่างปุ่มแอนิเมชันที่มีการเปลี่ยนขนาดเมื่อกดและเอฟเฟกต์ ripple บน Android ปุ่มดังกล่าวแทนที่การรวมกันของ TouchableOpacity + Animated

js
const AnimatedButton = ({ title, onPress }) => {
  const scale = React.useRef(new Animated.Value(1)).current;

  const handlePressIn = () => {
    Animated.spring(scale, {
      toValue: 0.96,
      useNativeDriver: true,
    }).start();
  };

  const handlePressOut = () => {
    Animated.spring(scale, {
      toValue: 1,
      friction: 3,
      useNativeDriver: true,
    }).start();
  };

  return (
    <Pressable
      onPress={onPress}
      onPressIn={handlePressIn}
      onPressOut={handlePressOut}
      android_ripple={{ color: 'rgba(255,255,255,0.3)' }}
      style={styles.button}>
      <AnimatedView style={[styles.inner, { transform: [{ scale }] }]}>
        <Text style={styles.text}>{title}</Text>
      </AnimatedView>
    </Pressable>
  );
};

สำคัญ: ใช้ useNativeDriver: true สำหรับแอนิเมชันใน Pressable ซึ่งจะย้ายแอนิเมชันไปยังเธรดเนทีฟ ป้องกันการหลุดของเฟรมระหว่างการกดเร็ว native driver รองรับ transform และ opacity บนทุกแพลตฟอร์ม

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

ฉันสามารถใช้ Pressable แทน TouchableOpacity โดยไม่เปลี่ยนโค้ดได้หรือไม่?

ไม่ได้ Pressable มี API ที่แตกต่างกัน TouchableOpacity ใช้ความโปร่งใสโดยอัตโนมัติเมื่อกด Pressable ต้องการระบุสไตล์อย่างชัดเจนผ่านฟังก์ชันสถานะ การแทนที่ทำได้ง่าย: ส่ง style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}

วิธีสร้างเอฟเฟกต์ ripple แบบ Material Design?

ใช้ prop android_ripple กับออบเจ็กต์ { color, borderless } สี ripple ระบุในรูปแบบ rgba สำหรับปุ่มกลม ใช้ borderless: true Ripple ทำงานบน Android 5+ เท่านั้น บน iOS ใช้แอนิเมชันแบบกำหนดเอง

ทำไม onPress ไม่ทำงานเมื่อเลื่อนเร็ว?

Pressable มีการป้องกันในตัวต่อการกดโดยไม่ตั้งใจระหว่างการเลื่อน หากผู้ใช้เลื่อนรายการ onPress จะไม่ถูกเรียก พฤติกรรมนี้สามารถกำหนดค่าได้ผ่าน pressRetentionOffset และ delayPressIn

วิธีติดตามการกดค้างด้วย Pressable?

ใช้ prop onLongPress — รองรับการกดค้างในตัว การหน่วงเวลากำหนดค่าได้ผ่าน delayLongPress (ค่าเริ่มต้น 500 ms) สำหรับเมนูบริบทและการลากและวาง ให้รวม onLongPress กับ onPressIn

Pressable รองรับการนำทางด้วยแป้นพิมพ์หรือไม่?

ใช่ Pressable รองรับสถานะ focused สำหรับการนำทางด้วยแป้นพิมพ์บน Android TV, Apple TV และ Web ใช้การจัดแต่งสไตล์ผ่าน { focused } เพื่อแสดงโฟกัส บนอุปกรณ์มือถือ สถานะ focused ไม่เกี่ยวข้อง

สรุป

  • Pressable — คอมโพเนนท์ React Native อเนกประสงค์สำหรับจัดการการสัมผัส แทนที่ TouchableOpacity, TouchableHighlight และ TouchableWithoutFeedback
  • สถานะ pressed, hovered, focused ส่งต่อไปยังฟังก์ชันสไตล์ ช่วยให้ปรับแต่งการตอบสนองสำหรับแต่ละสถานการณ์
  • hitSlop ขยายเป้าหมายสัมผัสเป็น 44×44 จุดโดยไม่เปลี่ยนขนาดที่มองเห็น ปรับปรุง UX บนองค์ประกอบขนาดเล็ก
  • API ประกอบด้วย onPress, onLongPress, onPressIn, onPressOut พร้อมหน่วงเวลาที่กำหนดค่าได้ผ่าน delayLongPress
  • android_ripple เพิ่มเอฟเฟกต์ ripple แบบ Material Design บน Android 5+ ด้วยสีและรูปทรงที่ปรับแต่งได้
  • การย้ายจาก Touchable ต้องการแทนที่เอฟเฟกต์อัตโนมัติด้วยการจัดแต่งสไตล์อย่างชัดเจนผ่านฟังก์ชันสถานะ
  • Animated + Pressable สร้างแอนิเมชันการกดที่ราบรื่นด้วย useNativeDriver เพื่อประสิทธิภาพ

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

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

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

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