TL; DR我正在制作可重用的Button
功能组件。我的按钮标签的useState()
钩子正在每个Button
实例上更新。我该如何预防?
我对React和构建Book Finder应用程序很陌生,以便学习。到目前为止,我的应用程序有一个BookList
和一个ReadingList
。任一列表中的每个BookDetail
都有一个Button
,可以从ReadingList
中添加/删除该书。添加/删除功能可以正常使用,但使用useState
更新Button
的标签将更新Button
组件的每个实例,而不仅仅是单击的那个实例。
Buttons
中书籍上的[[BookList
]以标签“添加到阅读列表”开头,但是如果我单击其中的any,则其中的[[all更新为“从阅读列表中删除”。
我曾尝试将逻辑移到Button
组件或List
组件中,但最终导致功能中断。App.jsfunction 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>
)
}
codesandbox中的未样式示例:https://codesandbox.io/s/cool-rgb-fksrp
<Button label={label} onClick={() => addOrRemove(book)} />
<button className='btn' onClick={onClick}>
button
中传递event
而不是book
作为函数参数const books = useState([{ label: 'Add to reading list', addRemove: true }])
然后:
function addOrRemove(book) {
if( book.addRemove ) {
handleAddBook(book)
book.label = 'Remove from Reading List'
book.addOrRemove = false
} else {
handleRemoveBook(book)
book.label = 'Add to Reading List'
book.addOrRemove = true
}
}
这样,每本书都有自己的标签。