Я создаю приложение для поиска книг, чтобы изучить React. Я не могу понять, как добавить книгу из списка всех книг ("Список книг") в отдельный "Список для чтения". У меня есть файл данных JSON книг, который выглядит так:
[
{
"descr": "Take a voyeuristic look at life in Sheffield...",
"author": "Philip Hensher",
"title_id": "9812",
"title": "The Northern Clemency",
"cover": "https://www.whichbook.net/assets/images/big/9812.jpg",
"similar": "https://www.whichbook.net/#cmd=search&search-type=3&id=9812"
},
...
]
и я перебираю их в своем компоненте BookList.js, чтобы отобразить каждую книгу и кнопку «Добавить в список для чтения» следующим образом:
export default function BookList ({ handleAddBook }) {
return (
<div>
{BookData.map((book) => {
return (
<>
<BookDetail key={book.title_id} book={book} />
<button onClick={handleAddBook}>Add to Reading List</button>
</>
)
})}
</div>
)
}
Для каждого BookDetail я просто отображаю заголовок и title_id. В BookDetail.js:
export default function BookDetail({ book }) {
return (
<div>
<h1>{book.title}</h1>
<p>{book.title_id}</p>
</div>
)
}
Это прекрасно работает. Я вижу список всех моих книг. Теперь в моем ReadingList.js я пытаюсь просмотреть книги, подобные моему BookList, за исключением того, что функциональный компонент имеет аргумент booksToRead
:
export default function ReadingList({ booksToRead }) {
return (
<div>
<h3>My Reading List</h3>
{booksToRead.map((book) => {
return (
<>
<BookDetail key={book.title_id} book={book} />
</>
)
})}
</div>
)
}
Хорошо, а теперь давайте посмотрим на App.js, где я попытался решить эту проблему. В основном я пытаюсь использовать useState()
и useEffect()
для обновления моего массива booksToRead
всякий раз, когда изменяется константа newBookToRead
, которая обрабатывается в функции handleAddBook
. Я инициализировал booksToRead
фиктивными данными, и они отображаются в браузере, но никогда не обновляются.
function App() {
const [books, setBooks] = useState([])
const [booksToRead, setBooksToRead] = useState([{ title: 'initialBookToRead', title_id: '1234' }])
const [newBookToRead, setNewBookToRead] = useState([{ title: 'addMe', title_id: '000' }])
function handleAddBook() {
setNewBookToRead(newBookToRead)
}
useEffect(() => {
setBooksToRead(booksToRead => [...booksToRead, newBookToRead])
}, [newBookToRead])
return (
<main>
<BookList books={books} />
<ReadingList booksToRead={booksToRead} />
</main>
);
}
export default App;
Я пытался перенести логику на разные компоненты, я пытался создать ReadingListContext с createContext
и использовать ReadingListContext.Provider value={booksToRead}
вместо тега <ReadingList>
, я просто не могу понять.
Кроме того, потенциально несвязанный, моя консоль дает мне Warning: Each child in a list should have a unique "key" prop.
для BookList
и ReadingList
, хотя я установил ключ на book.title_id
, который является уникальным кодом. ????