如何避免在React.js中使用useState挂钩来更新函数组件的所有实例?

问题描述 投票:0回答:2

TL; DR我正在制作可重用的Button功能组件。我的按钮标签的useState()钩子正在每个Button实例上更新。我该如何预防?

我对React和构建Book Finder应用程序很陌生,以便学习。到目前为止,我的应用程序有一个BookList和一个ReadingList。任一列表中的每个BookDetail都有一个Button,可以从ReadingList中添加/删除该书。添加/删除功能可以正常使用,但使用useState更新Button的标签将更新Button组件的每个实例,而不仅仅是单击的那个实例。

[Buttons中书籍上的[[BookList]以标签“添加到阅读列表”开头,但是如果我单击其中的

any,则其中的[[all更新为“从阅读列表中删除”。

我曾尝试将逻辑移到Button组件或List组件中,但最终导致功能中断。App.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>
    )
}

codesandbox中的未样式示例:https://codesandbox.io/s/cool-rgb-fksrp

javascript reactjs react-hooks instance react-component
2个回答
0
投票

<Button label={label} onClick={() => addOrRemove(book)} />

    <button className='btn' onClick={onClick}>
  • 看起来像在button中传递event而不是book作为函数参数

  • 0
    投票
    例如:

    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
        }
    }
    

    这样,每本书都有自己的标签。

    © www.soinside.com 2019 - 2024. All rights reserved.