[英]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.