рдЖрдЬ рдореИрдВ рдЖрдкрдХреЛ рджрд┐рдЦрд╛рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рдПрдХ рдпреВрдЬрдбреНрдпреВрдЬ рд╣реБрдХ рдмрдирд╛рдпрд╛ рдЬрд╛рдП рдЬреЛ рдЖрдкрдХреЛ рд╕реБрдкрд░-рд╕рд┐рдВрдкрд▓ рдПрдкреАрдЖрдИ рдХреЙрд▓ рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡реЗ рдмрд╣реБрдд рдмрд╛рд░ рди рд╣реЛрдВред
рдореИрдВрдиреЗ рдПрдХ рдбреЗрдореЛ рднреА рдмрдирд╛рдпрд╛ рдЬреЛ рд╣рдорд╛рд░реЗ рд╣реБрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдорд╛рд░реНрд╡рд▓ рдХреЙрдорд┐рдХреНрд╕ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпреВрдЬрд╝рдбрд┐рдмреНрдпреВрд╢рди рд╣реБрдХ рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдХреАрд╕реНрдЯреНрд░реЛрдХ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреЙрд▓ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдмрд╣реБрдд рд╕реБрдВрджрд░, рд╣реБрд╣? рдареАрдХ рд╣реИ, рдЕрдм рдХреЛрдб рдХреЗ рд▓рд┐рдП рдЪрд▓реЛ!
, , . , , , . useEffect, , . useState useEffect, .
import React, { useState, useEffect } from 'react';
import useDebounce from './use-debounce';
function App() {
const [searchTerm, setSearchTerm] = useState('');
const [results, setResults] = useState([]);
const [isSearching, setIsSearching] = useState(false);
const debouncedSearchTerm = useDebounce(searchTerm, 500);
useEffect(
() => {
if (debouncedSearchTerm) {
setIsSearching(true);
searchCharacters(debouncedSearchTerm).then(results => {
setIsSearching(false);
setResults(results);
});
} else {
setResults([]);
}
},
[debouncedSearchTerm]
);
return (
<div>
<input
placeholder="Search Marvel Comics"
onChange={e => setSearchTerm(e.target.value)}
/>
{isSearching && <div>Searching ...</div>}
{results.map(result => (
<div key={result.id}>
<h4>{result.title}</h4>
<img
src={`${result.thumbnail.path}/portrait_incredible.${
result.thumbnail.extension
}`}
/>
</div>
))}
</div>
);
}
function searchCharacters(search) {
const apiKey = 'f9dfb1e8d466d36c27850bedd2047687';
const queryString `apikey=${apiKey}&titleStartsWith=${search}`;
return fetch(
`https://gateway.marvel.com/v1/public/comics?${queryString}`,
{
method: 'GET'
}
)
.then(r => r.json())
.then(r => r.data.results)
.catch(error => {
console.error(error);
return [];
});
}
, ! , .
import React, { useState, useEffect } from 'react';
export default function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(
() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
},
[value]
);
return debouncedValue;
}
рдФрд░ рдпрд╣рд╛рдБ рд╡рд╣ рдЖрдкрдХреЗ рд╕рд╛рдордиреЗ рд╣реИ! рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрд╕реНрдердЧрд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реБрдХ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рд╕реАрдзреЗ рдХрд┐рд╕реА рднреА рдореВрд▓реНрдп рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдореЗрдВ рджреЗрд░реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрд╕реНрдердЧрд┐рдд рдореВрд▓реНрдп рдХреЛ рддрдм рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдирд┐рд░реНрднрд░рддрд╛ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмрдЬрд╛рдп рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рднрд╛рд╡ рдХреЛ рдХреЙрд▓ рдХреА рдЖрд╡реГрддреНрддрд┐ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рдпрд╣рд╛рдБ CodeSandbox рдкрд░ рдорд╛рд░реНрд╡рд▓ рдХреЙрдорд┐рдХ рд╕рд░реНрдЪ рдбреЗрдореЛ рдбреЗрдореЛ рд╣реИред
рдЕрдЧрд░ рдЖрдкрдХреЛ рдпрд╣ рдкрд╕рдВрдж рдЖрдпрд╛ рд╣реИ, рддреЛ рдЖрдк рдореЗрд░реЗ рдмреНрд▓реЙрдЧ рдХреЛ рд░рд┐рдПрдХреНрдЯ рд╣реБрдХ рдФрд░ рд░рд┐рдПрдХреНрдЯ рдРрдк рдмрд┐рд▓реНрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ ред