Dengan Bereaksi 16.8.6 (itu bagus pada versi sebelumnya 16.8.3), saya mendapatkan kesalahan ini ketika saya mencoba untuk mencegah loop tak terbatas pada permintaan pengambilan
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
Saya tidak dapat menemukan solusi yang menghentikan infinite loop. Saya ingin tinggal jauh dari menggunakan useReducer()
. Saya memang menemukan diskusi ini https://github.com/facebook/react/issues/14920 di mana solusi yang memungkinkan adalah You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.
saya tidak yakin dengan apa yang saya lakukan jadi saya belum mencoba mengimplementasikannya dulu.
Saya memiliki pengaturan saat ini React hook useEffect berjalan terus menerus selamanya / infinite loop dan satu-satunya komentar adalah tentang useCallback()
yang saya tidak kenal.
Bagaimana saya saat ini menggunakan useEffect()
(yang saya hanya ingin menjalankan sekali di awal mirip dengan componentDidMount()
)
useEffect(() => {
fetchBusinesses();
}, []);
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// some stuff
})
.catch(err => {
// some error handling
});
};
useCallback()
. Jadi misalnya:const fetchBusinesses= useCallback(() => { ... }, [...])
danuseEffect()
akan terlihat seperti ini:useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);
// eslint-disable-next-line react-hooks/exhaustive-deps
untuk menjelaskan kepada linter bahwa kode Anda benar seperti hack. Saya berharap mereka akan menemukan solusi lain untuk membuat linter lebih pintar untuk dideteksi ketika sebuah argumen tidak wajibIni bukan JS / React error tetapi peringatan eslint (eslint-plugin-react-hooks).
Ini memberi tahu Anda bahwa kait tergantung pada fungsinya
fetchBusinesses
, jadi Anda harus meneruskannya sebagai ketergantungan.Itu bisa mengakibatkan memanggil fungsi setiap render jika fungsi dideklarasikan dalam komponen seperti:
karena setiap fungsi waktu dideklar ulang dengan referensi baru
Cara yang benar dalam melakukan hal ini adalah:
atau hanya mendefinisikan fungsi dalam
useEffect
Lebih lanjut: https://github.com/facebook/react/issues/14920
sumber
Line 20: The 'fetchBusinesses' function makes the dependencies of useEffect Hook (at line 51) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'fetchBusinesses' definition into its own useCallback() Hook
Anda dapat mengaturnya langsung sebagai
useEffect
panggilan balik:Ini akan memicu hanya sekali, jadi pastikan semua dependensi fungsi diatur dengan benar (sama seperti menggunakan
componentDidMount/componentWillMount...
)Edit 02/21/2020
Hanya untuk kelengkapan:
1. Gunakan fungsi sebagai
useEffect
panggilan balik (seperti di atas)2. Nyatakan fungsi di dalamnya
useEffect()
3. Memoize dengan
useCallback()
Dalam hal ini, jika Anda memiliki dependensi dalam fungsi Anda, Anda harus memasukkannya dalam
useCallback
array dependensi dan ini akan memicuuseEffect
lagi jika params fungsi berubah. Selain itu, ini banyak boilerplate ... Jadi langsung saja operasikan fungsinyauseEffect
seperti pada1. useEffect(fetchBusinesses, [])
.4. Nonaktifkan peringatan eslint
sumber
Solusi ini juga diberikan oleh react, saran yang Anda gunakan
useCallback
yang akan mengembalikan versi memoize dari fungsi Anda:useCallback
mudah digunakan karena memiliki tanda tangan yang sama karenauseEffect
perbedaannya adalah useCallback mengembalikan fungsi. Akan terlihat seperti ini:sumber
Peringatan ini sangat membantu untuk menemukan komponen yang tidak diperbarui secara konsisten: https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- ketergantungan .
Namun, Jika Anda ingin menghapus peringatan di seluruh proyek Anda, Anda dapat menambahkan ini ke konfigurasi eslint Anda:
sumber
Artikel ini adalah primer yang bagus untuk mengambil data dengan kait: https://www.robinwieruch.de/react-hooks-fetch-data/
Pada dasarnya, sertakan definisi fungsi pengambilan di dalam
useEffect
:sumber
Anda dapat menghapus larik tipe argumen 2
[]
tetapifetchBusinesses()
akan juga dipanggil setiap pembaruan. Anda dapat menambahkanIF
pernyataan ke dalamfetchBusinesses()
implementasi jika Anda mau.Yang lainnya adalah mengimplementasikan
fetchBusinesses()
fungsi di luar komponen Anda. Hanya saja, jangan lupa memberikan argumen ketergantungan padafetchBusinesses(dependency)
panggilan Anda , jika ada.sumber
Sebenarnya peringatan itu sangat berguna ketika Anda berkembang dengan kait. tetapi dalam beberapa kasus, itu bisa menusuk Anda. terutama ketika Anda tidak perlu mendengarkan perubahan dependensi.
Jika Anda tidak ingin memasukkan
fetchBusinesses
dependensi hook, Anda bisa meneruskannya sebagai argumen ke callback hook dan mengatur mainfetchBusinesses
sebagai nilai default untuk itu seperti iniIni bukan praktik terbaik tetapi bisa bermanfaat dalam beberapa kasus.
Juga seperti yang ditulis Shubnam, Anda dapat menambahkan kode di bawah ini untuk memberi tahu ESLint untuk mengabaikan pemeriksaan untuk kail Anda.
sumber
Anda dapat menarik
fetchBusinesses
sepenuhnya dari komponen Anda:Ini tidak hanya akan memberikan solusi sederhana dan menyelesaikan peringatan deps-lengkap.
fetchBusiness
sekarang dapat diuji lebih baik dan lebih mudahComp
, karena berada dalam lingkup modul di luar pohon Bereaksi.Pindah ke
fetchBusinesses
luar berfungsi dengan baik di sini, karena kami hanya akan dapat membaca alat peraga awal dan menyatakan dari komponen karena ruang lingkup penutupan basi ([]
dep inuseEffect
).Bagaimana menghilangkan dependensi fungsi
useEffect
tergantung pada nilai ini (fungsi komputasi murni)useCallback
sebagai upaya terakhirMengenai solusi lain:
Menarik ke
fetchBusinesses
dalamuseEffect()
tidak terlalu membantu, jika Anda mengakses keadaan lain di dalamnya. eslint masih akan mengeluh: Codesandbox .Saya juga akan menahan diri dari eslint-deps mengabaikan komentar. Hanya untuk mudah melupakan mereka ketika Anda melakukan refactoring dan perbaikan dependensi Anda.
sumber
Solusi ini cukup sederhana dan Anda tidak perlu mengesampingkan peringatan es-lint. Cukup pertahankan bendera untuk memeriksa apakah komponen sudah terpasang atau tidak.
sumber
kamu coba cara ini
dan
ini bekerja untukmu. Tapi saran saya coba cara ini juga bekerja untuk Anda. Lebih baik dari sebelumnya. Saya menggunakan cara ini:
jika Anda mendapatkan data berdasarkan id tertentu kemudian tambahkan callback useEffect
[id]
maka Anda tidak dapat menampilkan peringatanReact Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array
sumber
cukup nonaktifkan eslint untuk baris berikutnya;
dengan cara ini Anda menggunakannya seperti komponen melakukan mount (dipanggil sekali)
diperbarui
atau
fetchBusinesses akan dipanggil setiap kali beberapaDEP akan berubah
sumber
[fetchBusinesses]
akan secara otomatis menghapus peringatan dan itu memecahkan masalah bagi saya.useEffect
yang memeriksa apakah keadaan kosong.