useMemo: มันคืออะไร การแคชคำนวณและ React Native

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

ฮุก useMemo ใน React Native จดจำผลลัพธ์ของการคำนวณระหว่างการเรนเดอร์คอมโพเนนต์ ป้องกันการดำเนินการซ้ำของการทำงานที่ใช้ทรัพยากรสูง แตกต่างจาก useCallback ที่จดจำฟังก์ชัน useMemo จะเก็บค่าที่ส่งคืนและคำนวณใหม่เมื่อดีเพนเดนซีที่ระบุเปลี่ยนแปลงเท่านั้น ตาม React Docs, 2024 การจดจำค่ามีประสิทธิภาพเป็นพิเศษสำหรับการคำนวณกับอาร์เรย์ขนาดใหญ่และการแปลงข้อมูลที่ซับซ้อน ใน React Native การเรนเดอร์ซ้ำที่ไม่จำเป็นทุกครั้งสร้างภาระเพิ่มเติมบนการเชื่อมต่อบริดจ์ระหว่าง JavaScript และเธรดเนทีฟ ดังนั้นการใช้ useMemo อย่างถูกต้องส่งผลโดยตรงต่อความลื่นไหลของแอนิเมชันและความเร็วในการตอบสนองของอินเทอร์เฟซ

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

  • useMemo — ฮุก React สำหรับจดจำค่า ซึ่งแคชผลลัพธ์ของฟังก์ชันระหว่างการเรนเดอร์
  • ฮุกรับ สองอาร์กิวเมนต์: ฟังก์ชันคำนวณและอาร์เรย์ดีเพนเดนซี
  • ค่าจะถูก คำนวณใหม่ เฉพาะเมื่อดีเพนเดนซีอย่างน้อยหนึ่งตัวเปลี่ยนแปลง
  • ใน React Native useMemo มีความสำคัญต่อการปรับแต่ง ประสิทธิภาพ ของรายการและแอนิเมชัน
  • การใช้ useMemo มากเกินไปอาจ ทำให้ ประสิทธิภาพแย่ลงเนื่องจากต้นทุนการเปรียบเทียบดีเพนเดนซี

useMemo ใน React Native คืออะไร

useMemo — คือฮุกจากไลบรารีมาตรฐานของ React ที่พร้อมใช้งานใน React Native โดยไม่ต้องมีแพ็กเกจเพิ่มเติม มันจดจำค่าที่ส่งคืนโดยฟังก์ชันที่ส่งผ่านและนำค่านี้กลับมาใช้ใหม่ในการเรนเดอร์ครั้งต่อไปจนกว่าดีเพนเดนซีที่ระบุในอาร์เรย์จะเปลี่ยนแปลง

ชื่อของฮุกมาจาก memoization — เทคนิคการปรับแต่งซึ่งผลลัพธ์ของฟังก์ชันที่ใช้ทรัพยากรสูงถูกเก็บไว้ในแคช ในการเรียกครั้งต่อไปด้วยอาร์กิวเมนต์เดียวกัน ค่าที่เก็บไว้ในแคชจะถูกส่งคืนแทนการคำนวณใหม่

ในบริบทของ React Native การจดจำค่ามีความสำคัญเป็นพิเศษเนื่องจากคุณลักษณะทางสถาปัตยกรรม การเรนเดอร์ซ้ำของคอมโพเนนต์ทุกครั้งส่งข้อมูลผ่าน บริดจ์ JavaScript — เนทีฟ ซึ่งใช้เวลา หากคอมโพเนนต์มีการคำนวณที่ใช้ทรัพยากรสูง (การกรองรายการ การเรียงลำดับ การจัดรูปแบบ) การเรนเดอร์ซ้ำทุกครั้งจะทำซ้ำการคำนวณเหล่านั้น บล็อกเธรด JS และทำให้เฟรมดรอป

ตาม React Native Performance Docs, 2024 คอขวดมักไม่ใช่การเรนเดอร์คอมโพเนนต์เนทีฟ แต่เป็นการดำเนินการโลจิก JavaScript ระหว่างการเรนเดอร์ useMemo แก้ไขปัญหานี้โดยเฉพาะ

การจดจำค่าทำงานอย่างไร

useMemo รับฟังก์ชันและอาร์เรย์ดีเพนเดนซี ส่งคืนค่าที่จดจำไว้ React เก็บค่าก่อนหน้าและอาร์เรย์ดีเพนเดนซี ในการเรนเดอร์แต่ละครั้ง React เปรียบเทียบดีเพนเดนซีปัจจุบันกับค่าก่อนหน้าโดยใช้ Object.is หากดีเพนเดนซีอย่างน้อยหนึ่งตัวเปลี่ยนแปลง ฟังก์ชันจะถูกดำเนินการอีกครั้งและผลลัพธ์จะถูกเก็บไว้

ไวยากรณ์และการส่งอาร์กิวเมนต์

ลายเซ็นของ useMemo เหมือนกันบนเว็บและใน React Native อาร์กิวเมนต์แรกคือฟังก์ชันที่ไม่มีพารามิเตอร์ซึ่งส่งคืนค่าที่จะจดจำ อาร์กิวเมนต์ที่สองคืออาร์เรย์ดีเพนเดนซี ซึ่งเมื่อเปลี่ยนแปลงจะทำให้ค่าถูกคำนวณใหม่

js
import React, { useMemo } from 'react';

const sortedList = useMemo(() => {
    return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);

ในตัวอย่างนี้ sortedList จะถูกคำนวณใหม่เมื่อการอ้างอิงไปยังอาร์เรย์ items เปลี่ยนแปลงเท่านั้น หากเนื้อหาอาร์เรย์เปลี่ยนแต่การอ้างอิงยังคงเดิม (การกลายพันธุ์) useMemo จะไม่ตรวจพบการเปลี่ยนแปลง — นี่เป็นข้อจำกัดที่สำคัญ

การเปรียบเทียบดีเพนเดนซีผ่าน Object.is

React ใช้อัลกอริทึม Object.is เพื่อเปรียบเทียบดีเพนเดนซี ซึ่งทำงานคล้ายกับการเท่ากันอย่างเข้มงวด === แต่จัดการ NaN อย่างถูกต้อง (+0 และ -0 ถือว่าแตกต่าง) ซึ่งหมายความว่าสำหรับชนิดดั้งเดิม (สตริง ตัวเลข บูลีน) การเปรียบเทียบทำงานตามค่า ในขณะที่สำหรับออบเจกต์และอาร์เรย์ — ตามการอ้างอิง

js
// Object.is({'a': 1}, {'a': 1}) -> false (different refs)
// Object.is(42, 42) -> true (primitive by value)
// Object.is(NaN, NaN) -> true (correct handling of NaN)

การทำความเข้าใจกลไกนี้มีความสำคัญ: หากคุณส่ง ออบเจกต์ใหม่ ในดีเพนเดนซีทุกครั้งที่เรนเดอร์ การจดจำค่าจะไร้ประโยชน์เพราะดีเพนเดนซีจะถูกพิจารณาว่าเปลี่ยนแปลงทุกครั้ง

เมื่อใดควรใช้ useMemo

useMemo มีความสมเหตุสมผลในสามสถานการณ์: การคำนวณที่ใช้ทรัพยากรสูง การส่ง props ที่เสถียรให้กับคอมโพเนนต์ลูก และการรักษาเอกลักษณ์การอ้างอิงของออบเจกต์ ใน React Native ทั้งสามสถานการณ์เกิดขึ้นเป็นประจำเนื่องจากสถาปัตยกรรมของแอปพลิเคชันมือถือ

การคำนวณที่ใช้ทรัพยากรสูง

หากคอมโพเนนต์ประมวลผล อาร์เรย์ข้อมูลขนาดใหญ่ (การกรอง การเรียงลำดับ การจัดกลุ่ม) หรือดำเนินการทางคณิตศาสตร์ที่ใช้ทรัพยากรมาก useMemo ป้องกันการทำซ้ำการคำนวณเหล่านี้ในการเรนเดอร์ซ้ำทุกครั้ง ในแอปพลิเคชันมือถือ ตัวอย่างทั่วไปคือการจัดรูปแบบข้อมูลจาก API ก่อนแสดงในรายการ

Props ที่เสถียรสำหรับคอมโพเนนต์ลูก

เมื่อคอมโพเนนต์ลูกถูกห่อหุ้มใน React.memo มันจะเรนเดอร์ซ้ำเมื่อ props ของมันเปลี่ยนแปลงเท่านั้น หากออบเจกต์ prop ถูกสร้างขึ้นภายในคอมโพเนนต์แม่โดยไม่มี useMemo การอ้างอิงใหม่จะถูกสร้างขึ้นในการเรนเดอร์แม่ทุกครั้ง และคอมโพเนนต์ลูกจะเรนเดอร์ซ้ำโดยไม่จำเป็น ทำให้ประโยชน์ของ React.memo เป็นโมฆะ

การจดจำการคำนวณสไตล์

ใน React Native สไตล์มักขึ้นอยู่กับ props — ตัวอย่างเช่น ความกว้างขององค์ประกอบคำนวณตาม ขนาดหน้าจอ useMemo อนุญาตให้คำนวณสไตล์ไดนามิกดังกล่าวเมื่อพารามิเตอร์อินพุตเปลี่ยนแปลงเท่านั้น

เมื่อใด useMemo ไร้ประโยชน์

useMemo ไม่ใช่เครื่องมือปรับแต่งสากล ในหลายสถานการณ์ มันไม่ได้ให้ประโยชน์และอาจทำให้ประสิทธิภาพแย่ลงเนื่องจากค่าใช้จ่ายในการจัดเก็บและเปรียบเทียบดีเพนเดนซี ใน React Native ที่ทุกไบต์ของหน่วยความจำมีความสำคัญ การใช้ useMemo อย่างไม่เลือกโดยไม่วัดผลเป็นสิ่งที่ไม่ควรทำ

ฮุกไม่มีประโยชน์ในสามกรณีหลัก ประการแรก หากการคำนวณ เล็กน้อย (การบวกง่าย การต่อสตริง) ต้นทุนของ useMemo เกินต้นทุนของการคำนวณเอง ประการที่สอง หากดีเพนเดนซี เปลี่ยนแปลงทุกการเรนเดอร์ — ฟังก์ชันจะยังคงถูกดำเนินการ และการจดจำค่าเพียงเพิ่มงานพิเศษ ประการที่สาม หากคอมโพเนนต์เรนเดอร์ไม่บ่อย ค่าใช้จ่ายในการจัดเก็บแคชก็ไม่สมเหตุสมผล

ตาม Kent C. Dodds, 2023 ก่อนเพิ่ม useMemo คุณควรวัดปัญหาด้วย React DevTools Profiler หรือ Performance Monitor ในตัวของ React Native หากการเรนเดอร์ซ้ำของคอมโพเนนต์ใช้เวลาน้อยกว่า 1 มิลลิวินาที — ไม่จำเป็นต้องจดจำค่า

  • การคำนวณเล็กน้อย — การบวก การต่อสตริง การดำเนินการแบบ ternary ธรรมดา
  • การเรนเดอร์ซ้ำที่หายาก — หน้าจอคงที่ที่เรนเดอร์ครั้งเดียว
  • ดีเพนเดนซีที่เปลี่ยนไป — หากดีเพนเดนซีใหม่ทุกการเรนเดอร์ การจดจำค่าไร้ประโยชน์
  • ค่าดั้งเดิม — ตัวเลขและสตริงไม่ต้องการการจดจำค่า มันมีต้นทุนต่ำอยู่แล้ว

useMemo และ useCallback: การเปรียบเทียบ

useMemo และ useCallback — ฮุกการจดจำค่าสองตัวของ React ที่มักสับสน ความแตกต่างอยู่ที่สิ่งที่พวกเขาเก็บรักษา: useMemo ส่งคืนผลลัพธ์ของการดำเนินการฟังก์ชัน (ค่าใดๆ) ในขณะที่ useCallback ส่งคืนฟังก์ชันเอง ทั้งสองรับอาร์เรย์ดีเพนเดนซี แต่ไวยากรณ์แตกต่างกัน

คุณลักษณะuseMemouseCallback
ส่งคืนผลลัพธ์ของการดำเนินการฟังก์ชันการอ้างอิงถึงฟังก์ชัน
อาร์กิวเมนต์แรกฟังก์ชันที่ส่งคืนค่าฟังก์ชันที่จะจดจำ
การใช้งานทั่วไปการแคชการคำนวณ Callback ที่เสถียรสำหรับคอมโพเนนต์ลูก
ความเท่าเทียมuseMemo(() => fn, deps)useCallback(fn, deps) === useMemo(() => fn, deps)

ในทางปฏิบัติ useCallback คือ น้ำตาลเชิงไวยากรณ์ เหนือ useMemo สำหรับกรณีที่คุณต้องการจดจำฟังก์ชัน ใน React Native ฮุกทั้งสองถูกใช้บ่อยเท่าๆ กัน: useMemo — สำหรับข้อมูล (ข้อความที่จัดรูปแบบแล้ว สไตล์ที่คำนวณแล้ว) useCallback — สำหรับตัวจัดการเหตุการณ์ (onPress, onChangeText)

ตัวอย่างเชิงปฏิบัติกับ useMemo

มาดูสองสถานการณ์จริงของการใช้ useMemo ในแอปพลิเคชัน React Native อย่างแรกคือการกรองรายชื่อผู้ติดต่อตามคำค้นหา อย่างที่สองคือการคำนวณสไตล์ไดนามิกตามขนาดหน้าจอ

ตัวอย่างที่ 1: การค้นหาและกรองรายการ

ในตัวอย่างนี้ useMemo ป้องกันการกรองซ้ำของ รายชื่อผู้ติดต่อจำนวนมาก ในการเรนเดอร์ทุกครั้งหากทั้งคำค้นหาและข้อมูลต้นทางไม่เปลี่ยนแปลง

js
const ContactList = ({ contacts, searchQuery }) => {
    const filteredContacts = useMemo(() => {
        if (!searchQuery.trim()) return contacts;
        const query = searchQuery.toLowerCase();
        return contacts.filter((c) =>
            c.name.toLowerCase().includes(query) ||
            c.phone.includes(query)
        );
    }, [contacts, searchQuery]);

    return (
        <FlatList
            data={filteredContacts}
            renderItem={renderContact}
            keyExtractor={(item) => item.id}
        />
    );
};

หากไม่มี useMemo การกรองจะดำเนินการใน ทุกการเรนเดอร์ รวมถึงการเรนเดอร์ที่เกิดจากแอนิเมชันหรือการเปลี่ยนแปลงสถานะในส่วนอื่นของคอมโพเนนต์ ด้วย useMemo การกรองจะทำงานเมื่อ contacts หรือ searchQuery เปลี่ยนแปลงเท่านั้น

ตัวอย่างที่ 2: การคำนวณสไตล์ไดนามิก

ใน React Native สไตล์มักขึ้นอยู่กับ ขนาดหน้าจอ หรือ props ของคอมโพเนนต์ useMemo อนุญาตให้คำนวณออบเจกต์สไตล์ดังกล่าวครั้งเดียวและนำกลับมาใช้ใหม่จนกว่าดีเพนเดนซีจะเปลี่ยนแปลง

js
const Card = ({ title, isSelected }) => {
    const cardStyle = useMemo(() => ({
        backgroundColor: isSelected ? '#e3f2fd' : '#ffffff',
        borderWidth: isSelected ? 2 : 1,
        padding: 16,
    }), [isSelected]);

    return (
        <View style={cardStyle}>
            <Text>{title}</Text>
        </View>
    );
};

วิธีการนี้รับประกันว่าออบเจกต์ cardStyle จะคงที่ (การอ้างอิงเดียวกัน) จนกว่า isSelected จะเปลี่ยนแปลง หาก Card ถูกห่อหุ้มใน React.memo รูปแบบนี้จะป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็นขององค์ประกอบลูก

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

useMemo ส่งคืนอะไร?

useMemo ส่งคืน ค่าที่จดจำไว้ — ผลลัพธ์ของการดำเนินการฟังก์ชันที่ส่งเป็นอาร์กิวเมนต์แรก ในการเรนเดอร์ครั้งต่อไป React จะส่งคืนค่าที่แคชไว้หากดีเพนเดนซีไม่เปลี่ยนแปลง

useMemo แตกต่างจาก useCallback อย่างไร?

useMemo ส่งคืน ผลลัพธ์ ของการดำเนินการฟังก์ชัน (ค่าใดๆ: ตัวเลข ออบเจกต์ JSX) ในขณะที่ useCallback ส่งคืน ฟังก์ชันเอง โปรดทราบว่า useCallback(fn, deps) เทียบเท่ากับ useMemo(() => fn, deps)

เมื่อใดที่ไม่จำเป็นต้องใช้ useMemo?

useMemo ไร้ประโยชน์สำหรับ การคำนวณเล็กน้อย (การบวก การต่อสตริง) การเรนเดอร์ซ้ำที่หายาก ดีเพนเดนซีที่เปลี่ยนแปลงทุกการเรนเดอร์ และชนิดดั้งเดิม วัดประสิทธิภาพก่อนเพิ่ม useMemo เสมอ

useMemo ทำให้ประสิทธิภาพแย่ลงได้หรือไม่?

ได้ หากใช้โดยไม่จำเป็น React เก็บค่าก่อนหน้า ในหน่วยความจำ และเปรียบเทียบดีเพนเดนซีทุกการเรนเดอร์ สำหรับการคำนวณธรรมดา ค่าใช้จ่ายของการดำเนินการเหล่านี้เกินประโยชน์ของการจดจำค่า

จะดีบักพฤติกรรมของ useMemo ได้อย่างไร?

ใช้ React DevTools Profiler เพื่อวัดเวลาเรนเดอร์ของคอมโพเนนต์ ใน React Native Performance Monitor ก็สามารถเข้าถึงได้ผ่านเมนูนักพัฒนา หากการเรนเดอร์ซ้ำใช้เวลาน้อยกว่า 1 มิลลิวินาที — ไม่จำเป็นต้องใช้ useMemo

สรุป

  • useMemo — ฮุก React สำหรับจดจำค่า ซึ่งแคชผลลัพธ์ของฟังก์ชันระหว่างการเรนเดอร์
  • ฮุกรับฟังก์ชันคำนวณและอาร์เรย์ ดีเพนเดนซี คำนวณค่าใหม่เมื่อมีการเปลี่ยนแปลงเท่านั้น
  • ใน React Native useMemo สำคัญเป็นพิเศษสำหรับการปรับแต่ง รายการ แอนิเมชันและการคำนวณที่ซับซ้อน
  • สถานการณ์หลัก: การคำนวณที่ใช้ทรัพยากรสูง props ที่เสถียรสำหรับ React.memo สไตล์ไดนามิก
  • useMemo แตกต่างจาก useCallback: อย่างแรกส่งคืนค่า อย่างหลังส่งคืน ฟังก์ชัน
  • การใช้ useMemo มากเกินไปทำให้ประสิทธิภาพลดลงเนื่องจาก ค่าใช้จ่าย ในการจัดเก็บและเปรียบเทียบดีเพนเดนซี
  • ก่อนเพิ่ม useMemo วัดปัญหาด้วย React DevTools Profiler หรือ Performance Monitor ใน React Native เสมอ

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

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

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

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