解決React報錯React?Hook?useEffect?has?a?missing?dependency
總覽
當(dāng)useEffect鉤子使用了一個我們沒有包含在其依賴數(shù)組中的變量或函數(shù)時,會產(chǎn)生"React Hook useEffect has a missing dependency"警告。為了解決該錯誤,禁用某一行的eslint規(guī)則,或者將變量移動到useEffect鉤子內(nèi)。

這里有個示例用來展示警告是如何發(fā)生的。
// 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鉤子內(nèi)部使用了obj變量,但我們沒有在其依賴數(shù)組中包含該變量。
最明顯的解決方法是將obj變量添加到useEffect鉤子的依賴數(shù)組中。然而,在本例中,它將導(dǎo)致一個錯誤,因為在JavaScript中,對象和數(shù)組是通過引用進(jìn)行比較的。
obj變量是一個對象,在每次重新渲染時都有相同的鍵值對,但它每次都指向內(nèi)存中的不同位置,所以它將無法通過相等檢查并導(dǎo)致無限的重新渲染循環(huán)。
在JavaScript中,數(shù)組也是通過引用進(jìn)行比較。
禁用規(guī)則
繞過"React Hook useEffect has a missing dependency"警告的一個方法是禁用某一行的eslint規(guī)則。
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>
);
}
依賴數(shù)組上方的注釋禁用了單行的react-hooks/exhausting-deps規(guī)則。
當(dāng)useEffect鉤子的第二個參數(shù)傳遞的是空數(shù)組時,只有當(dāng)組件掛載或者卸載時才會調(diào)用。
依賴移入
另一種解決辦法是,將變量或者函數(shù)聲明移動到useEffect鉤子內(nèi)部。
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鉤子里面。這就消除了警告,因為鉤子不再依賴對象,對象聲明在鉤子內(nèi)部。
依賴移出
另一個可能的解決方案是將函數(shù)或變量的聲明移出你的組件,這可能很少使用,但最好知道。
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組件時,變量不會每次都重新創(chuàng)建。該變量在所有渲染中都會指向內(nèi)存的相同位置,因此useEffect不需要在其依賴數(shù)組中跟蹤它。
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鉤子接收一個函數(shù),該函數(shù)返回一個要被記憶的值和一個依賴數(shù)組作為參數(shù)。該鉤子只有在其中一個依賴項發(fā)生變化時才會重新計算記憶值。
useCallback
請注意,如果你正在使用一個函數(shù),你將使用useCallback鉤子來獲得一個在渲染期間不會改變的記憶回調(diào)。
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鉤子接收一個內(nèi)聯(lián)回調(diào)函數(shù)和一個依賴數(shù)組,并返回一個記憶化版本的回調(diào),該回調(diào)只在其中一個依賴發(fā)生變化時才會改變。
如果這些建議對你都不起作用,你總是可以用注釋來消滅警告。
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的詳細(xì)內(nèi)容,更多關(guān)于React 報錯解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在react中使用highlight.js將頁面上的代碼高亮的方法
本文通過 highlight.js 庫實現(xiàn)對文章正文 HTML 中的代碼元素自動添加語法高亮,具有一定的參考價值,感興趣的可以了解一下2022-01-01
React實現(xiàn)控制減少useContext導(dǎo)致非必要的渲染詳解
這篇文章主要介紹了React如何有效減少使用useContext導(dǎo)致的不必要渲染,使用useContext在改變一個數(shù)據(jù)時,是通過自己逐級查找對比改變的數(shù)據(jù)然后渲染,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-11-11
React為什么需要Scheduler調(diào)度器原理詳解
這篇文章主要為大家介紹了React為什么需要Scheduler調(diào)度器原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
基于React實現(xiàn)調(diào)用式Modal組件的全流程
本文基于 nextUI 和 tailwindCSS 實現(xiàn)調(diào)用式 Modal 組件的封裝,文中通過圖文結(jié)合的方式和代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2024-12-12

