Задача за React: реализирайте компонент за търсене на срещания на подниз в текст. Изисквания: зареждане на текст от API при първото рендиране, индикация за зареждане, обработка на грешки, търсене на срещания без значение на големината на буквите, подчертаване на намерените срещания, показване на общия брой срещания, бутон за зареждане на допълнителен текст.
sobes.tech AI
Отговор от AI
jsx import React, { useState, useEffect } from 'react';
function SearchComponent() { const [text, setText] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [query, setQuery] = useState(''); const [matches, setMatches] = useState([]);
const fetchText = async () => { setLoading(true); setError(null); try { const response = await fetch('/api/text'); if (!response.ok) throw new Error('Ошибка загрузки'); const data = await response.text(); setText(prev => prev + data); } catch (e) { setError(e.message); } finally { setLoading(false); } };
useEffect(() => { fetchText(); }, []);
useEffect(() => { if (!query) { setMatches([]); return; } const regex = new RegExp(query, 'gi'); const found = []; let match; while ((match = regex.exec(text)) !== null) { found.push({ start: match.index, end: regex.lastIndex }); } setMatches(found); }, [query, text]);
const highlightText = () => { if (!matches.length) return text; const parts = []; let lastIndex = 0; matches.forEach(({ start, end }, i) => { parts.push(text.slice(lastIndex, start)); parts.push(<mark key={i}>{text.slice(start, end)}</mark>); lastIndex = end; }); parts.push(text.slice(lastIndex)); return parts; };
return ( <div> {loading && <p>Загрузка...</p>} {error && <p style={{ color: 'red' }}>{error}</p>} <input type="text" placeholder="Поиск" value={query} onChange={e => setQuery(e.target.value)} /> <button onClick={fetchText} disabled={loading}>Загрузить ещё</button> <p>Найдено вхождений: {matches.length}</p> <div style={{ whiteSpace: 'pre-wrap' }}>{highlightText()}</div> </div> ); }
export default SearchComponent;