[英]How can I use AbortController in Next js?
我的應用程序允許用戶在搜索框中鍵入內容時進行搜索並獲得建議。 每次用戶輸入字符時,我都會使用“獲取”從 API 中獲取建議。問題在於,如果用戶進行快速搜索,他可以在獲取建議之前得到結果。 在這種情況下,我想取消獲取請求。
我曾經在 React 中擁有相同的應用程序,我可以使用 AbortController 輕松取消請求,但這在 Next.js 中不起作用。
我做了一些研究,我認為問題正在發生,因為 Next 在嘗試生成頁面時無法訪問 AbortController。
當我嘗試使用“window.innerWidth”時,我也遇到了這個問題,因為 Next 似乎也無法訪問“window”。
我找到的解決方案是使用“useEffect”。 當我將它與“窗口”一起使用時,它工作得很好。
const [size, setSize] = useState(0)
useEffect(() => {
setSize(window.innerWidth)
}, [])
但是當我使用 AbortController 時它不起作用。 首先我是這樣做的:
let suggestionsController;
useEffect(() => {
suggestionsController = new AbortController();
},[])
但是當我嘗試使用“suggestionsController”時,它總是未定義。
所以我嘗試使用“useRef”做同樣的事情。
const suggestionsControllerRef = useRef(null)
useEffect(() => {
suggestionsControllerRef.current = new AbortController();
},[])
這就是我獲取建議的方式:
async function fetchSuggestions (input){
try {
const response = await fetch(`url/${input}`, {signal: suggestionsControllerRef.current.signal})
const result = await response.json()
setSuggestionsList(result)
} catch (e) {
console.log(e)
}
}
這就是我中止請求的方式:
function handleSearch(word) {
suggestionsControllerRef.current.abort()
router.push(`/dictionary/${word}`)
setShowSuggestions(false)
}
一切都第一次完美運行。 但是,如果用戶嘗試進行另一次搜索,“fetchSuggestions”function 將停止工作,並且我在控制台中收到此錯誤“DOMException:無法在‘Window’上執行‘fetch’:用戶中止了請求”。
有誰知道在 Next.js 中使用 AbortController 的正確方法是什么?
我發現該問題的解決方案是每次用戶進行搜索時創建一個新的 AbortController 實例。 在顯示建議時,“showSuggestions”為真,但在調用“handleSearch”時,“showSuggestions”設置為假。 所以我只是將它作為依賴項添加到 useEffect 中。
useEffect(() => {
const obj = new AbortController();
setSuggestionController(obj)
},[showSuggestions])
我也從 useRef 切換到 useState,但我不確定這是否有必要,因為我沒有使用 useRef 測試此解決方案。
我不知道這是否是在 Next js 中使用 AbortController 的最佳方式,但我的應用程序現在按預期工作。
我想如果用戶停止輸入,你可以嘗試 abort controller 來取消你的請求,但這不是解決這個常見問題的標准方法。
您想要“去抖動”用戶鍵入時運行的回調。 去抖動是一種策略,它本質上是捕獲 function 調用並在執行 function 之前“等待”一定時間。例如,在這種情況下,您可能希望對搜索 function 進行去抖動,以便它僅在 500 毫秒后運行一次用戶已經停止打字,而不是在每次按鍵時都運行。
查看去抖動庫或自己編寫去抖動 function,但公平警告一開始它可能非常棘手!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.