Kosongkan Dependensi dengan useMemo atau useCallback VS useRef

9

Dalam masalah GitHub ini saya pada dasarnya mengusulkan perubahan:

x = useCallback( ... , []);

Untuk:

x = useRef( ... ).current;

Keduanya sama tetapi dengan useRefBereaksi tidak membandingkan dependensi.

Untuk itu balasan datang dengan pertanyaan:

Apakah pernah ada situasi di mana ketergantungan-kurang useMemo atau useCallback akan menjadi pilihan yang lebih baik daripada useRef?

Saya tidak bisa memikirkan satu, tetapi saya mungkin telah mengabaikan beberapa kasus penggunaan.

Jadi, adakah yang bisa memikirkan situasi seperti itu?

Izhaki
sumber

Jawaban:

5

Dokumentasi Per React Hooks API:

Ingatlah bahwa useRef tidak memberi tahu Anda ketika kontennya berubah. Mematikan properti .current tidak menyebabkan render ulang ... Menggunakan callback ref memastikan bahwa bahkan jika komponen anak menampilkan simpul yang diukur kemudian (misalnya sebagai respons terhadap klik), kami masih mendapatkan pemberitahuan tentang hal itu di induknya komponen dan dapat memperbarui pengukuran.

Anda dapat membaca lebih lanjut tentang ini di sini dan di sini .

irasuna
sumber
Saya kira ini menjawab pertanyaan, tapi saya kira ini tidak benar. Dalam contoh kotak pasir Bereaksi, mengubah useCallback(x,[])untuk useRef(x)bekerja sama.
Izhaki
useRef(x).currentitu adalah.
Izhaki
Saya harap saya salah, tetapi saya telah membuat alasan mengapa dokumen salah: github.com/reactjs/reactjs.org/issues/2570
Izhaki
Saya tidak sepenuhnya yakin tentang useCallback(cb, [])vs useRef(cb).currentsaya sendiri. Meskipun, useMemo(cb, [])berbeda useRef(cb).currentdalam arti bahwa useMemo, "hanya akan menghitung ulang nilai memoized ketika salah satu dependensi telah berubah." Versus useRefyang selalu menghitung ulang nilai apa pun yang terjadi.
irasuna
useReftidak pernah menghitung ulang - selalu mengembalikan nilai awal.
Izhaki
1

Meskipun Anda dapat menggunakan useRef untuk meniru useCallback atau dengan dependensi kosong, Anda tidak dapat menggunakannya untuk semua skenario yang mungkin dari useCallback yang digunakan untuk melakukan rememoisasi ketika salah satu dari dependensi berubah.

Juga tidak akan membuat banyak perbedaan kinerja jika Anda menggunakan useCallback with empty dependencyatau menggunakanRef karena tidak harus melakukan perbandingan berat.

Juga jika Anda mengubah implementasi fungsi sedikit sehingga Anda harus membuatnya kembali pada perubahan param tertentu, Anda dapat memperbarui implementasi dengan useCallbackdan menambahkan param tambahan sebagai ketergantungan. Namun jika Anda menerapkannya dengan useRef, Anda harus kembali keuseCallback

Shubham Khatri
sumber
1
Terima kasih. Seperti judulnya, ini adalah kasus ketergantungan yang benar-benar kosong.
Izhaki
1
@Izhaki Saya mengerti pertanyaan Anda adalah dependensi kosong dan itu sebabnya saya sebutkan bahwa tidak ada perbedaan dalam hal ketergantungan kosong. Tetapi ketika Anda mencoba untuk menambahkan lebih banyak perubahan, Anda mungkin perlu sedikit refactor
Shubham Khatri
0

Karena output dari useRef (() => {...}). Current dapat berubah.

Yang dapat menyebabkan Efek samping yang aneh dalam kode Anda. Saya dapat mengubah nilai arus setiap saat. https://codesandbox.io/s/confident-monad-vjeuw

Itu akan menjadi usecase karena tidak ingin menggunakan useRef

Daniel Duong
sumber
1
Tetapi x = useRef(value).currenttidak pernah mengembalikan contoh yang bisa berubah - reftidak pernah dikembalikan; currentadalah. Itu sama dengan useCallbackversi.
Izhaki