解決React報錯React Hook useEffect has a missing dependency
總覽
當useEffect
鉤子使用瞭一個我們沒有包含在其依賴數組中的變量或函數時,會產生"React Hook useEffect has a missing dependency"警告。為瞭解決該錯誤,禁用某一行的eslint
規則,或者將變量移動到useEffect
鉤子內。
這裡有個示例用來展示警告是如何發生的。
// App.js import React, {useEffect, useState} from 'react'; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); // 👇️ objects/arrays are different on re-renders const obj = {country: 'Chile', city: 'Santiago'}; useEffect(() => { setAddress(obj); console.log('useEffect called'); // ⛔️ React Hook useEffect has a missing dependency: 'obj'. // Either include it or remove the dependency array. eslintreact-hooks/exhaustive-deps }, []); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
上述代碼片段的問題在於,我們在useEffect
鉤子內部使用瞭obj
變量,但我們沒有在其依賴數組中包含該變量。
最明顯的解決方法是將obj
變量添加到useEffect
鉤子的依賴數組中。然而,在本例中,它將導致一個錯誤,因為在JavaScript中,對象和數組是通過引用進行比較的。
obj
變量是一個對象,在每次重新渲染時都有相同的鍵值對,但它每次都指向內存中的不同位置,所以它將無法通過相等檢查並導致無限的重新渲染循環。
在JavaScript中,數組也是通過引用進行比較。
禁用規則
繞過"React Hook useEffect has a missing dependency"警告的一個方法是禁用某一行的eslint
規則。
import React, {useEffect, useState} from 'react'; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); const obj = {country: 'Chile', city: 'Santiago'}; useEffect(() => { setAddress(obj); console.log('useEffect called'); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
依賴數組上方的註釋禁用瞭單行的react-hooks/exhausting-deps
規則。
當useEffect
鉤子的第二個參數傳遞的是空數組時,隻有當組件掛載或者卸載時才會調用。
依賴移入
另一種解決辦法是,將變量或者函數聲明移動到useEffect
鉤子內部。
import React, {useEffect, useState} from 'react'; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); useEffect(() => { // 👇️ move object / array / function declaration // inside of the useEffect hook const obj = {country: 'Chile', city: 'Santiago'}; setAddress(obj); console.log('useEffect called'); }, []); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
我們把對象的變量聲明移到瞭useEffect
鉤子裡面。這就消除瞭警告,因為鉤子不再依賴對象,對象聲明在鉤子內部。
依賴移出
另一個可能的解決方案是將函數或變量的聲明移出你的組件,這可能很少使用,但最好知道。
import React, {useEffect, useState} from 'react'; // 👇️ move function/variable declaration outside of component const obj = {country: 'Chile', city: 'Santiago'}; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); useEffect(() => { setAddress(obj); console.log('useEffect called'); }, []); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
這是很有用的,因為每次重新渲染App組件時,變量不會每次都重新創建。該變量在所有渲染中都會指向內存的相同位置,因此useEffect
不需要在其依賴數組中跟蹤它。
useMemo
另一個解決方案是使用useMemo
鉤子來得到一個記憶值。
import React, {useMemo, useEffect, useState} from 'react'; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); // 👇️ get memoized value const obj = useMemo(() => { return {country: 'Chile', city: 'Santiago'}; }, []); useEffect(() => { setAddress(obj); console.log('useEffect called'); // 👇️ safely include in dependencies array }, [obj]); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
我們使用useMemo
鉤子得到一個記憶值,該值在渲染期間不會改變。
useMemo
鉤子接收一個函數,該函數返回一個要被記憶的值和一個依賴數組作為參數。該鉤子隻有在其中一個依賴項發生變化時才會重新計算記憶值。
useCallback
請註意,如果你正在使用一個函數,你將使用useCallback
鉤子來獲得一個在渲染期間不會改變的記憶回調。
import React, {useMemo, useEffect, useState, useCallback} from 'react'; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); // 👇️ get memoized callback const sum = useCallback((a, b) => { return a + b; }, []); // 👇️ get memoized value const obj = useMemo(() => { return {country: 'Chile', city: 'Santiago'}; }, []); useEffect(() => { setAddress(obj); console.log('useEffect called'); console.log(sum(100, 100)); // 👇️ safely include in dependencies array }, [obj, sum]); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
useCallback
鉤子接收一個內聯回調函數和一個依賴數組,並返回一個記憶化版本的回調,該回調隻在其中一個依賴發生變化時才會改變。
如果這些建議對你都不起作用,你總是可以用註釋來消滅警告。
import React, {useEffect, useState} from 'react'; export default function App() { const [address, setAddress] = useState({country: '', city: ''}); const obj = {country: 'Chile', city: 'Santiago'}; useEffect(() => { setAddress(obj); console.log('useEffect called'); // 👇️ disable the rule for a single line // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( <div> <h1>Country: {address.country}</h1> <h1>City: {address.city}</h1> </div> ); }
原文鏈接:bobbyhadz.com/blog/react-…
以上就是解決React報錯React Hook useEffect has a missing dependency的詳細內容,更多關於React 報錯解決的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- React-Hook中使用useEffect清除定時器的實現方法
- 如何解決React useEffect鉤子帶來的無限循環問題
- React Hook用法示例詳解(6個常見hook)
- React編程中需要註意的兩個錯誤
- React中10種Hook的使用介紹