1 回答

TA貢獻1995條經驗 獲得超2個贊
我提供了解決方案,@JacobSmit 在評論部分進行了解釋。現在我只是把它們整理成一個更詳細的答案,希望對后來者有所幫助。
解決方案
const useSearch = (query: string, sources: string[]) => {
// ...
useEffect(() => {
// ...
// FIX:
// just apply the spread operator (...) to `sources`
// to spread its elements into the dependency array of `useEffect`
}, [query, ...sources]);
return response;
};
解釋
自useSearch定義掛鉤傳遞[query, sources]到 的 dep 數組useEffect,其中 assources: string[]本身就是一個數組。這使得 dep 數組的形狀為:
["query", ["source_1", "source_2", ..., "source_n"]]
看到 dep 數組的第二個元素是一個嵌套數組。useEffect然而,使用 dep 數組的方法是Object.is對其每個元素應用相等檢查:
// pseudo code
function isDepArrayEqual(prevDepArray: any[], currDepArray: any[]) {
return prevDepArray.every(
(prevElement, index) => Object.is(prevElement, currDepArray[index])
)
}
每次重新渲染時,鉤子調用useSearch("Donald", ["bbc-news"])都會創建一個新的數組實例sources。這將使檢查失敗Object.is(prevSources, currSources),因為數組的相等性是通過它們的引用來比較的,而不是它們包含的值。
使用擴展運算符[query, ...sources],您可以將 dep 數組的形狀轉換為:
["query", "source_1", "source_2", ..., "source_n"]
關鍵區別不在于復制,而在于解壓數組sources。
現在嵌套sources數組已解包,并且 dep 數組的每個元素只是字符串。對字符串的相等性檢查是通過它們的值而不是引用進行比較,因此useEffect將認為 dep 數組不變。錯誤已修復。
添加回答
舉報