英文:
How to use async/await syntax with the debunce function in react?
问题
以下是您要翻译的代码部分:
const { useState, useMemo } = React;
function debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, ...args), delay);
}
}
const getApi = (terms) => `https://www.reddit.com/search.json?q=${terms}`;
const Search = () => {
const DELAY = 500;
const [text, setText] = useState("");
const [list, setList] = useState([]);
const fetchData = useMemo(debounce(async(evt) => {
const res = await fetch(getApi(evt.target.value));
const {data} = await res.json();
setList(data.children.map(d => d.data.title));
}, DELAY), []);
return (
<div>
<form className="bg-gray-200 p-5">
<input
type="text"
name="text"
placeholder="search users..."
value={text}
onChange={(e) => {
setText(e.target.value);
fetchData(e);
}
}
className="bg-white p-2 w-3/4 outline-none"
/>
</form>
<ul>
{list.map(title => <li>{title}</li>)}
</ul>
</div>
);
};
ReactDOM.render(<Search />, document.getElementById("app"));
希望这能帮助您解决问题。如果您有任何其他问题,请随时提出。
英文:
Trying to create an react autocomplete component and use debounce
function to reduce frequent api call. The code is following:
const { useState, useMemo } = React;
function debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, ...args), delay);
}
}
const getApi = (terms) => `https://www.reddit.com/search.json?q=${terms}`;
const Search = () => {
const DELAY = 500;
const [text, setText] = useState("");
const [list, setList] = useState([]);
const fetchData = useMemo(debounce(async(evt) => {
const res = await fetch(getApi(evt.target.value));
const {data} = await res.json();
setList(data.children.map(d => d.data.title));
}, DELAY), []);
return (
<div>
<form className="bg-gray-200 p-5">
<input
type="text"
name="text"
placeholder="search users..."
value={text}
onChange={(e) => {
setText(e.target.value);
fetchData(e);
}
}
className="bg-white p-2 w-3/4 outline-none"
/>
</form>
<ul>
{list.map(title => <li>{title}</li>)}
</ul>
</div>
);
};
ReactDOM.render(<Search />, document.getElementById("app"));
The api call has not been made after I test it from console. Any idea where goes wrong?
答案1
得分: 0
以下是代码部分的翻译:
The signature of useMemo
is
const memoizedValue = useMemo(functionThatCreatesMemoizedValue, [dependencies]);
The first argument passed to it is executed immediately. But you have
const fetchData = useMemo(debounce(......), []);
debounce
returns a debounced function; that debounced function is then called immediately by useMemo
, and the return value is put into fetchData
.
What you need to do is have a function that returns the debounced function.
const fetchData = useMemo(() => debounce(......), []);
For a memoized value that's a callback, you can also consider using useCallback
instead, which works nearly identically but is arguably a bit more semantically appropriate.
const fetchData = useCallback(debounce((evt) => {
console.log('api call');
}, DELAY), []);
希望对您有所帮助。
英文:
The signature of useMemo
is
const memoizedValue = useMemo(functionThatCreatesMemoizedValue, [dependencies]);
The first argument passed to it is executed immediately. But you have
const fetchData = useMemo(debounce(......), []);
debounce
returns a debounced function; that debounced function is then called immediately by useMemo
, and the return value is put into fetchData
.
What you need to do is have a function that returns the debounced function.
const fetchData = useMemo(() => debounce(......), []);
<!-- begin snippet: js hide: true console: true babel: true -->
<!-- language: lang-js -->
function debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, ...args), delay);
}
}
const Search = () => {
const DELAY = 500;
const [text, setText] = React.useState("");
const [list, setList] = React.useState([]);
const fetchData = React.useMemo(() => debounce((evt) => {
console.log('api call');
}, DELAY), []);
return (
<div>
<form className="bg-gray-200 p-5">
<input
type="text"
name="text"
placeholder="search users..."
value={text}
onChange={(e) => {
setText(e.target.value);
fetchData(e);
}
}
className="bg-white p-2 w-3/4 outline-none"
/>
</form>
<ul>
{list.map(title => <li>{title}</li>)}
</ul>
</div>
);
};
ReactDOM.createRoot(document.querySelector('.react')).render(<Search />);
<!-- language: lang-html -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>
<!-- end snippet -->
For a memoized value that's a callback, you can also consider using useCallback
instead, which works nearly identically but is arguably a bit more semantically appropriate.
const fetchData = useCallback(debounce((evt) => {
console.log('api call');
}, DELAY), []);
<!-- begin snippet: js hide: true console: true babel: true -->
<!-- language: lang-js -->
function debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, ...args), delay);
}
}
const Search = () => {
const DELAY = 500;
const [text, setText] = React.useState("");
const [list, setList] = React.useState([]);
const fetchData = React.useCallback(debounce((evt) => {
console.log('api call');
}, DELAY), []);
return (
<div>
<form className="bg-gray-200 p-5">
<input
type="text"
name="text"
placeholder="search users..."
value={text}
onChange={(e) => {
setText(e.target.value);
fetchData(e);
}
}
className="bg-white p-2 w-3/4 outline-none"
/>
</form>
<ul>
{list.map(title => <li>{title}</li>)}
</ul>
</div>
);
};
ReactDOM.createRoot(document.querySelector('.react')).render(<Search />);
<!-- language: lang-html -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论