Sobes.tech
Middle+

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;