TL; DR Я создаю компонент многократного использования Button
. Мой useState()
хук для метки кнопки обновляется каждый экземпляр Button
. Как я могу предотвратить это?
Я очень новичок в React и создаю приложение Book Finder для обучения. Пока что мое приложение имеет BookList
и ReadingList
. Каждый BookDetail
в любом списке имеет Button
для добавления / удаления этой книги из ReadingList
. Функция добавления / удаления работает (phew), но использование useState
для обновления метки Button
обновляет каждый экземпляр компонента Button
, а не только тот, который был нажат.
Buttons
для книг в BookList
начинаются с метки «Добавить в список чтения», но если я нажму любой из них, все из них обновятся до «Удалить из списка чтения» .
Я пытался переместить логи c в компонент Button
или в компонент List
, но я просто нарушил функцию.
Приложение. js
function App() {
const books = useState([])
const [booksToRead, setBooksToRead] = useState([])
const [addRemove, setAddRemove] = useState(true)
const [label, setLabel] = useState('Add to Reading List')
function handleAddBook(book) {
const newID = book.title_id
if( (typeof booksToRead.find(x => x.title_id === newID)) == 'undefined' ) {
setBooksToRead([...booksToRead, book])
}
}
function handleRemoveBook(book) {
console.log(book)
const array = booksToRead
const index = array.indexOf(book)
const newArray = [...array.slice(0, index), ...array.slice(index +1)]
setBooksToRead(newArray)
}
function addOrRemove(book) {
if( addRemove ) {
handleAddBook(book)
setLabel('Remove from Reading List')
setAddRemove(false)
} else {
handleRemoveBook(book)
setLabel('Add to Reading List')
setAddRemove(true)
}
}
return (
<main>
<BookList books={books} handleAddBook={handleAddBook} addOrRemove={addOrRemove} label={label} />
<ReadingList booksToRead={booksToRead} handleRemoveBook={handleRemoveBook} />
</main>
);
}
export default App;
BookList. js
function BookList ({ book, label, handleAddBook, addOrRemove }) {
return (
<div className="booklist">
{BookData.map((book, index) => {
const onAddBook = () => addOrRemove(book)
return (
<div key={index} className="card">
<BookDetail key={book.title_id} book={book} />
<Button key={index + 'btn'} label={label} onClick={onAddBook} />
</div>
)
})}
</div>
)
}
export default BookList
И, наконец, Button. js
export default function Button({ styleClass, label, onClick }) {
return (
<button className='btn' onClick={(event) => onClick(event)}>
{label}
</button>
)
}
Пример без стилей в codeandbox: https://codesandbox.io/s/cool-rgb-fksrp