Əvvəl özün sına, sonra müqayisə et. Bu, mümkün həllərdən biridir.
Kitablar unikal ID ilə saxlanır, vəziyyət yalnız yeni massiv/obyektlə yenilənir. localStorage işləməyəndə səhifə istifadəyə davam edir və xəbərdarlıq verir.
App.jsx
import { useEffect, useState } from 'react';
const key = 'book-tracker:v1';
function loadBooks() {
try {
const data = JSON.parse(localStorage.getItem(key) ?? '[]');
return Array.isArray(data) ? data.filter(book => book && typeof book.id === 'string' && typeof book.title === 'string' && typeof book.read === 'boolean') : [];
} catch { return []; }
}
export default function App() {
const [books, setBooks] = useState(loadBooks);
const [title, setTitle] = useState('');
const [query, setQuery] = useState('');
const [warning, setWarning] = useState('');
useEffect(() => {
try { localStorage.setItem(key, JSON.stringify(books)); setWarning(''); }
catch { setWarning('Yaddaş əlçatan deyil; dəyişikliklər yalnız bu səhifədə qalır.'); }
}, [books]);
function add(event) {
event.preventDefault(); if (!title.trim()) return;
const book = { id: crypto.randomUUID(), title: title.trim(), read: false };
setBooks(previous => [...previous, book]); setTitle('');
}
const visible = books.filter(book => book.title.toLocaleLowerCase('az').includes(query.toLocaleLowerCase('az')));
return <main><h1>Kitab izləyicisi</h1><form onSubmit={add}><label>Kitab adı<input value={title} onChange={event => setTitle(event.target.value)} /></label><button>Əlavə et</button></form>
<label>Axtar<input value={query} onChange={event => setQuery(event.target.value)} /></label>
{warning && <p role="status">{warning}</p>}
{visible.length ? <ul>{visible.map(book => <li key={book.id}><label><input type="checkbox" checked={book.read} onChange={() => setBooks(previous => previous.map(item => item.id === book.id ? { ...item, read: !item.read } : item))} />{book.title}</label></li>)}</ul> : <p>Kitab tapılmadı.</p>}
</main>;
}