解決React報(bào)錯(cuò)React?Hook?useEffect?has?a?missing?dependency
總覽
當(dāng)useEffect
鉤子使用了一個(gè)我們沒有包含在其依賴數(shù)組中的變量或函數(shù)時(shí),會產(chǎn)生"React Hook useEffect has a missing dependency"警告。為了解決該錯(cuò)誤,禁用某一行的eslint
規(guī)則,或者將變量移動到useEffect
鉤子內(nèi)。
這里有個(gè)示例用來展示警告是如何發(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)致一個(gè)錯(cuò)誤,因?yàn)樵贘avaScript中,對象和數(shù)組是通過引用進(jìn)行比較的。
obj
變量是一個(gè)對象,在每次重新渲染時(shí)都有相同的鍵值對,但它每次都指向內(nèi)存中的不同位置,所以它將無法通過相等檢查并導(dǎo)致無限的重新渲染循環(huán)。
在JavaScript中,數(shù)組也是通過引用進(jìn)行比較。
禁用規(guī)則
繞過"React Hook useEffect has a missing dependency"警告的一個(gè)方法是禁用某一行的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
鉤子的第二個(gè)參數(shù)傳遞的是空數(shù)組時(shí),只有當(dāng)組件掛載或者卸載時(shí)才會調(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
鉤子里面。這就消除了警告,因?yàn)殂^子不再依賴對象,對象聲明在鉤子內(nèi)部。
依賴移出
另一個(gè)可能的解決方案是將函數(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> ); }
這是很有用的,因?yàn)槊看沃匦落秩続pp組件時(shí),變量不會每次都重新創(chuàng)建。該變量在所有渲染中都會指向內(nèi)存的相同位置,因此useEffect
不需要在其依賴數(shù)組中跟蹤它。
useMemo
另一個(gè)解決方案是使用useMemo
鉤子來得到一個(gè)記憶值。
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
鉤子得到一個(gè)記憶值,該值在渲染期間不會改變。
useMemo
鉤子接收一個(gè)函數(shù),該函數(shù)返回一個(gè)要被記憶的值和一個(gè)依賴數(shù)組作為參數(shù)。該鉤子只有在其中一個(gè)依賴項(xiàng)發(fā)生變化時(shí)才會重新計(jì)算記憶值。
useCallback
請注意,如果你正在使用一個(gè)函數(shù),你將使用useCallback
鉤子來獲得一個(gè)在渲染期間不會改變的記憶回調(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
鉤子接收一個(gè)內(nèi)聯(lián)回調(diào)函數(shù)和一個(gè)依賴數(shù)組,并返回一個(gè)記憶化版本的回調(diào),該回調(diào)只在其中一個(gè)依賴發(fā)生變化時(shí)才會改變。
如果這些建議對你都不起作用,你總是可以用注釋來消滅警告。
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報(bào)錯(cuò)React Hook useEffect has a missing dependency的詳細(xì)內(nèi)容,更多關(guān)于React 報(bào)錯(cuò)解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React內(nèi)部實(shí)現(xiàn)cache方法示例詳解
這篇文章主要為大家介紹了React內(nèi)部實(shí)現(xiàn)cache方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11React Native AsyncStorage本地存儲工具類
這篇文章主要為大家分享了React Native AsyncStorage本地存儲工具類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10如何將你的AngularJS1.x應(yīng)用遷移至React的方法
本篇文章主要介紹了如何將你的AngularJS1.x應(yīng)用遷移至React的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼
本文主要介紹了react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02