取消上一个请求(如果有),然后在react中使用debouncing进行另一个请求



我当前使用的示例react代码。。。

我想在使用debouncing进行另一个请求时立即中止该请求。现在,它甚至第一次取消了它提出的请求。


import "./App.css";
import React, { useCallback, useState } from "react";
function App() {
const [mesg, setMesg] = useState(0);
const [pin, setPin] = useState("");
const abortCon = new AbortController();
const signal = abortCon.signal;
const debounce = (fn, timer) => {
let time;
return function () {
let arg = arguments;
let context = this;
if (time) clearTimeout(time);
time = setTimeout(() => {
fn.apply(context, arg);
time = null;
}, timer);
};
};
const onChangeHandler = (val) => {
const url = "https://jsonplaceholder.typicode.com/todos/1";
console.log(val);
if (abortCon) abortCon.abort();
fetch(url, { signal })
.then((result) => {
return result.json();
})
.then((res) => {
// const result = await res.json();
console.log(res.title);
setPin(val);
setMesg((prev) => prev + 1);
})
.catch((e) => console.log(e));
};
// const newHandler = debounce(onChangeHandler, 400);
const newHandler = useCallback(debounce(onChangeHandler, 200), []);
return (
<div className="App">
<p>{mesg}</p>
<input
type="text"
placeholder="PIN code"
value={pin}
onChange={(e) => {
setPin(e.target.value);
newHandler(e.target.value);
}}
/>
</div>
);
}
export default App;

我想在使用debouncing进行另一个请求时立即中止该请求。现在,它甚至第一次取消了它提出的请求。

问题是您没有为每个请求创建一个新的Abort Controller。

因此,我们使用useRef((将一个ref保存到AbortController。然后创建一个新的AbotrController,并在每个请求开始时将其分配给ref。

请参阅下面的更新代码:

import "./App.css";
import React, { useCallback, useRef, useState } from "react";
function App() {
const [mesg, setMesg] = useState(0);
const [pin, setPin] = useState("");
const abortConRef = useRef();
const debounce = (fn, timer) => {
let time;
return function () {
let arg = arguments;
let context = this;
if (time) clearTimeout(time);
time = setTimeout(() => {
fn.apply(context, arg);
time = null;
}, timer);
};
};
const onChangeHandler = (val) => {
const url = "https://jsonplaceholder.typicode.com/todos/1";
console.log(val);
if (abortConRef.current) abortConRef.current.abort();
abortConRef.current = new AbortController();
fetch(url, { signal: abortConRef.current.signal })
.then((result) => {
return result.json();
})
.then((res) => {
// const result = await res.json();
console.log(res.title);
// setPin(val);
setMesg((prev) => prev + 1);
})
.catch((e) => console.log(e));
};
// const newHandler = debounce(onChangeHandler, 400);
const newHandler = useCallback(debounce(onChangeHandler, 200), []);
return (
<div className="App">
<p>{mesg}</p>
<input
type="text"
placeholder="PIN code"
value={pin}
onChange={(e) => {
setPin(e.target.value);
newHandler(e.target.value);
}}
/>
</div>
);
}
export default App;

https://codesandbox.io/s/serene-wright-f85hy?file=/src/App.js

编辑:我还在响应回调中注释掉了setPin。它使输入错误。

最新更新