狀態設定器的react-hooks/exhaustive-deps警告有什麼意義?
P粉465287592
2023-09-01 22:11:31
<p>我正在使用 React 建立分頁。 </p>
<p>該應用程式使用狀態管理分頁和搜尋。我想在搜尋字詞更改時將分頁重設為第 1 頁。 </p>
<pre class="brush:php;toolbar:false;">// Simplified example
function useSearchTerm() {
return React.useState("");
}
function usePage() {
return React.useState(1);
}
function MyComponent(){
const [searchTerm, setSearchTerm] = useSearchTerm()
const [page, setPage] = usePage();
useEffect(() => {
setPage(1);
}, [searchTerm]); // <-- Here is the ESLint warning
}</pre>
<p>這給我帶來了 ESLint 警告 <code>React Hook useEffect 缺少依賴項:「setPage」。要麼包含它,要麼刪除 useEffect 掛鉤上的依賴項 array.eslintreact-hooks/exhaustive-deps。 </p>
<p>但是,當然,如果我在依賴項中包含 setPage,則每次渲染時都會呼叫該效果。 </p>
<p>我在這個用例上做錯了什麼嗎? </p>
這個中間函數似乎是問題所在:
由
useState
傳回的狀態設定函數本身不會在每次渲染時重新創建,但透過此外部函數呼叫它似乎會破壞這一點。這導致依賴項發生變化,如useEffect
依賴項數組所觀察到的。如果您不需要這個
usePage
函數(在範例中您不需要,但在更大的上下文中可能存在有意義的情況),那麼只需將其完全刪除並使用直接useState
:通常,人們無論如何都不想在函數內調用鉤子,因為它可以快速且輕鬆地導致違反必須在每次渲染上一致且以相同順序調用鉤子的規則。因此,最好將鉤子呼叫保留在元件本身的主體中(以及元件邏輯的早期)。
有時,在某些情況下,您確實希望自訂函數充當
useEffect
中的依賴項。由於聲明的函數在每次渲染時都會重新聲明,因此您會遇到上面遇到的問題。為了解決這個問題,您可以將函數包裝在useCallback
掛鉤中,該掛鉤本身也有一個相依性數組,與useEffect
非常相似。這個鉤子的目的是創建自訂函數,React 可以將這些函數跨渲染緩存為單一函數實例(除非依賴項發生變化)。例如: