useMemo: τι είναι, προσωρινή αποθήκευση υπολογισμών και React Native

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-07-05 Χρόνος ανάγνωσης: 10 λεπ

Το useMemo hook στο React Native απομνημονεύει το αποτέλεσμα υπολογισμών μεταξύ των ανανεώσεων του component, αποτρέποντας την επαναλαμβανόμενη εκτέλεση δαπανηρών λειτουργιών. Σε αντίθεση με το useCallback που απομνημονεύει τη συνάρτηση, το useMemo αποθηκεύει την επιστρεφόμενη τιμή και την επανυπολογίζει μόνο όταν αλλάξουν οι καθορισμένες εξαρτήσεις. Σύμφωνα με το React Docs, 2024, η απομνημόνευση είναι ιδιαίτερα αποτελεσματική για υπολογισμούς με μεγάλους πίνακες και σύνθετους μετασχηματισμούς δεδομένων. Στο React Native, κάθε επιπλέον επανανανέωση δημιουργεί επιπλέον φόρτο στη σύνδεση γέφυρας μεταξύ των νημάτων JavaScript και native, επομένως η σωστή χρήση του useMemo επηρεάζει άμεσα την ομαλότητα των κινήσεων και την ταχύτητα απόκρισης της διεπαφής.

Βασικά σημεία

  • useMemo — hook του React για απομνημόνευση τιμών, που αποθηκεύει προσωρινά το αποτέλεσμα συνάρτησης μεταξύ ανανεώσεων
  • Το hook δέχεται δύο ορίσματα: μια συνάρτηση υπολογισμού και έναν πίνακα εξαρτήσεων
  • Η τιμή επανυπολογίζεται μόνο όταν αλλάξει τουλάχιστον μία εξάρτηση
  • Στο React Native, το useMemo είναι κρίσιμο για τη βελτιστοποίηση της απόδοσης λιστών και κινήσεων
  • Η κατάχρηση του useMemo μπορεί να επιδεινώσει την απόδοση λόγω του κόστους σύγκρισης εξαρτήσεων

Τι είναι το useMemo στο React Native

useMemo — είναι ένα hook από την τυπική βιβλιοθήκη του React, διαθέσιμο στο React Native χωρίς επιπλέον πακέτα. Απομνημονεύει την τιμή που επιστρέφει η μεταβιβαζόμενη συνάρτηση και επαναχρησιμοποιεί αυτήν την τιμή σε επόμενες ανανεώσεις έως ότου αλλάξουν οι εξαρτήσεις που καθορίζονται στον πίνακα.

Το όνομα του hook προέρχεται από το αγγλικό memoization — μια τεχνική βελτιστοποίησης όπου το αποτέλεσμα μιας δαπανηρής συνάρτησης αποθηκεύεται στην προσωρινή μνήμη. Σε επαναλαμβανόμενη κλήση με τα ίδια ορίσματα, επιστρέφεται η αποθηκευμένη τιμή αντί για επανυπολογισμό.

Στο πλαίσιο του React Native, η απομνημόνευση είναι ιδιαίτερα σημαντική λόγω της αρχιτεκτονικής. Κάθε επανανανέωση του component στέλνει δεδομένα μέσω της γέφυρας JavaScript — Native, που απαιτεί χρόνο. Εάν το component περιέχει δαπανηρούς υπολογισμούς (φιλτράρισμα λίστας, ταξινόμηση, μορφοποίηση), κάθε επανανανέωση θα τους επαναλαμβάνει, μπλοκάροντας το νήμα JS και προκαλώντας πτώση καρέ.

Σύμφωνα με το React Native Performance Docs, 2024, το σημείο συμφόρησης συχνότερα δεν είναι η ανανέωση native components, αλλά η εκτέλεση λογικής 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 θεωρούνται διαφορετικά). Αυτό σημαίνει ότι για πρωτόγονους τύπους (συμβολοσειρές, αριθμοί, boolean) η σύγκριση λειτουργεί βάσει τιμής, και για αντικείμενα και πίνακες — βάσει αναφοράς.

js
// Object.is({'a': 1}, {'a': 1}) -> false (διαφορετικές αναφορές)
// Object.is(42, 42) -> true (πρωτόγονο βάσει τιμής)
// Object.is(NaN, NaN) -> true (σωστός χειρισμός NaN)

Η κατανόηση αυτού του μηχανισμού είναι κρίσιμη: εάν μεταβιβάζετε στις εξαρτήσεις ένα νέο αντικείμενο σε κάθε ανανέωση, η απομνημόνευση θα είναι άχρηστη, επειδή οι εξαρτήσεις θα θεωρούνται αλλαγμένες κάθε φορά.

Πότε να χρησιμοποιείτε το useMemo

useMemo δικαιολογείται σε τρία σενάρια: δαπανηροί υπολογισμοί, μεταβίβαση σταθερών props σε child components και διατήρηση της ταυτότητας αναφοράς αντικειμένων. Στο React Native, και τα τρία σενάρια εμφανίζονται τακτικά λόγω της αρχιτεκτονικής των εφαρμογών για κινητά.

Δαπανηροί υπολογισμοί

Εάν το component εκτελεί επεξεργασία μεγάλων πινάκων δεδομένων (φιλτράρισμα, ταξινόμηση, ομαδοποίηση) ή λειτουργίες μαθηματικών που απαιτούν πόρους, το useMemo αποτρέπει την επανάληψη αυτών των υπολογισμών σε κάθε επανανανέωση. Σε εφαρμογές για κινητά, ένα τυπικό παράδειγμα είναι η μορφοποίηση δεδομένων από API πριν από την εμφάνιση σε λίστα.

Σταθερά props για child components

Όταν το child component είναι τυλιγμένο σε React.memo, επανανανέωνεται μόνο όταν αλλάξουν τα props. Εάν το αντικείμενο props δημιουργείται μέσα στο parent χωρίς useMemo, σε κάθε ανανέωση του parent θα δημιουργείται νέα αναφορά, και το child component θα ανανεώνεται ξανά, ακυρώνοντας το όφελος του React.memo.

Απομνημόνευση υπολογισμών στυλ

Στο React Native, τα στυλ συχνά εξαρτώνται από τα props — για παράδειγμα, το πλάτος ενός στοιχείου υπολογίζεται βάσει του μεγέθους οθόνης. Το useMemo επιτρέπει τον υπολογισμό αυτών των δυναμικών στυλ μόνο όταν αλλάξουν οι παράμετροι εισόδου.

Πότε το useMemo είναι άχρηστο

useMemo δεν είναι ένα καθολικό εργαλείο βελτιστοποίησης. Σε ορισμένα σενάρια δεν προσφέρει όφελος και μπορεί ακόμη και να επιδεινώσει την απόδοση λόγω του πρόσθετου κόστους αποθήκευσης και σύγκρισης εξαρτήσεων. Στο React Native, όπου κάθε byte μνήμης μετράει, η τυφλή χρήση του useMemo χωρίς μέτρηση της επίδρασης είναι αντι-πρότυπο.

Το hook δεν προσφέρει όφελος σε τρεις κύριες περιπτώσεις. Πρώτον, εάν ο υπολογισμός είναι τετριμμένος (απλή πρόσθεση, συνένωση συμβολοσειρών), το κόστος του useMemo υπερβαίνει την αξία του ίδιου του υπολογισμού. Δεύτερον, εάν οι εξαρτήσεις αλλάζουν σε κάθε ανανέωση — η συνάρτηση θα εκτελείται ούτως ή άλλως, και η απομνημόνευση θα προσθέσει μόνο επιπλέον δουλειά. Τρίτον, εάν το component ανανεώνεται σπάνια, το πρόσθετο κόστος αποθήκευσης προσωρινής μνήμης δεν δικαιολογείται.

Σύμφωνα με το Kent C. Dodds, 2023, πριν προσθέσετε το useMemo, πρέπει να μετρήσετε το πρόβλημα χρησιμοποιώντας το React DevTools Profiler ή το ενσωματωμένο Performance Monitor στο React Native. Εάν η επανανανέωση του component διαρκεί λιγότερο από 1 ms, η απομνημόνευση δεν είναι απαραίτητη.

  • Τετριμμένοι υπολογισμοί — πρόσθεση, συνένωση, απλές τριαδικές λειτουργίες
  • Σπάνιες επανανανεώσεις — στατικές οθόνες που ανανεώνονται μία φορά
  • Μεταβαλλόμενες εξαρτήσεις — εάν οι εξαρτήσεις είναι νέες σε κάθε ανανέωση, η απομνημόνευση είναι άχρηστη
  • Πρωτόγονες τιμές — οι αριθμοί και οι συμβολοσειρές δεν χρειάζονται απομνημόνευση, είναι ήδη φθηνοί

useMemo και useCallback: σύγκριση

useMemo και useCallback — δύο hooks απομνημόνευσης από το React που συχνά συγχέονται. Η διαφορά έγκειται στο τι αποθηκεύουν: το useMemo επιστρέφει το αποτέλεσμα εκτέλεσης της συνάρτησης (οποιαδήποτε τιμή), ενώ το useCallback επιστρέφει την ίδια τη συνάρτηση. Και τα δύο δέχονται έναν πίνακα εξαρτήσεων, αλλά η σύνταξη διαφέρει.

ΧαρακτηριστικόuseMemouseCallback
ΕπιστρέφειΑποτέλεσμα εκτέλεσης συνάρτησηςΑναφορά στη συνάρτηση
Πρώτο όρισμαΣυνάρτηση που επιστρέφει τιμήΣυνάρτηση προς απομνημόνευση
Τυπική χρήσηΠροσωρινή αποθήκευση υπολογισμώνΣταθερά callbacks για child components
ΙσοδυναμίαuseMemo(() => fn, deps)useCallback(fn, deps) === useMemo(() => fn, deps)

Στην πράξη, το useCallback είναι συντακτική ζάχαρη πάνω από το useMemo για την περίπτωση που χρειάζεται να απομνημονευτεί μια συνάρτηση. Στο React Native, και τα δύο hooks χρησιμοποιούνται εξίσου συχνά: 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, το φιλτράρισμα θα εκτελούνταν σε κάθε ανανέωση, συμπεριλαμβανομένων αυτών που προκαλούνται από κινήσεις ή αλλαγή κατάστασης άλλων τμημάτων του component. Με useMemo, το φιλτράρισμα ενεργοποιείται μόνο όταν αλλάξουν τα contacts ή το searchQuery.

Παράδειγμα 2: υπολογισμός δυναμικών στυλ

Στο React Native, τα στυλ συχνά εξαρτώνται από το μέγεθος οθόνης ή τα props του component. Το 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, αυτό το μοτίβο αποτρέπει τις περιττές επανανανεώσεις των child στοιχείων.

Συχνές ερωτήσεις

Τι επιστρέφει το useMemo;

Το useMemo επιστρέφει την απομνημονευμένη τιμή — το αποτέλεσμα εκτέλεσης της συνάρτησης που δόθηκε ως πρώτο όρισμα. Στις επόμενες ανανεώσεις, το React επιστρέφει την αποθηκευμένη τιμή εάν οι εξαρτήσεις δεν έχουν αλλάξει.

Πώς διαφέρει το useMemo από το useCallback;

Το useMemo επιστρέφει το αποτέλεσμα εκτέλεσης της συνάρτησης (οποιαδήποτε τιμή: αριθμός, αντικείμενο, JSX), ενώ το useCallback επιστρέφει την ίδια τη συνάρτηση. Επιπλέον, το useCallback(fn, deps) είναι ισοδύναμο με το useMemo(() => fn, deps).

Πότε δεν χρειάζεται το useMemo;

Το useMemo είναι άχρηστο σε τετριμμένους υπολογισμούς (πρόσθεση, συνένωση), σπάνιες επανανανεώσεις, εξαρτήσεις που αλλάζουν σε κάθε ανανέωση και για πρωτόγονους τύπους. Πάντα να μετράτε την απόδοση πριν προσθέσετε useMemo.

Μπορεί το useMemo να επιδεινώσει την απόδοση;

Ναι, εάν χρησιμοποιείται χωρίς λόγο. Το React αποθηκεύει προηγούμενες τιμές στη μνήμη και εκτελεί σύγκριση εξαρτήσεων σε κάθε ανανέωση. Για απλούς υπολογισμούς, το πρόσθετο κόστος αυτών των λειτουργιών υπερβαίνει το όφελος της απομνημόνευσης.

Πώς να κάνετε debug τη λειτουργία του useMemo;

Χρησιμοποιήστε το React DevTools Profiler για μέτρηση του χρόνου ανανέωσης των components. Στο React Native, είναι επίσης διαθέσιμο το Performance Monitor μέσω του μενού προγραμματιστή. Εάν η επανανανέωση διαρκεί λιγότερο από 1 ms — το useMemo δεν χρειάζεται.

Σύνοψη

  • useMemo — hook του React για απομνημόνευση τιμών, που αποθηκεύει προσωρινά το αποτέλεσμα συνάρτησης μεταξύ ανανεώσεων
  • Το hook δέχεται μια συνάρτηση υπολογισμού και έναν πίνακα εξαρτήσεων, επανυπολογίζοντας την τιμή μόνο όταν αυτές αλλάζουν
  • Στο React Native, το useMemo είναι ιδιαίτερα σημαντικό για τη βελτιστοποίηση λιστών, κινήσεων και σύνθετων υπολογισμών
  • Βασικά σενάρια: δαπανηροί υπολογισμοί, σταθερά props για React.memo, δυναμικά στυλ
  • Το useMemo διαφέρει από το useCallback: το πρώτο επιστρέφει τιμή, το δεύτερο — συνάρτηση
  • Η κατάχρηση του useMemo επιδεινώνει την απόδοση λόγω του πρόσθετου κόστους αποθήκευσης και σύγκρισης εξαρτήσεων
  • Πριν προσθέσετε useMemo, πάντα να μετράτε το πρόβλημα μέσω React DevTools Profiler ή Performance Monitor στο React Native

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης