[在React中,当我在另一个组件中触发Add函数时,如何正确使用钩子来更新一个组件?

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

我正在构建一个用于查找书籍以学习React的应用。我无法弄清楚如何将我的all书籍列表(“书籍列表”)中的书籍添加到单独的“阅读列表”中。我有一个书籍的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和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;

[我尝试将逻辑转移到不同的组件,我尝试使用createContext创建一个ReadingListContext并使用ReadingListContext.Provider value={booksToRead}而不是<ReadingList>标签,但我想不出来。

也可能是不相关的,即使我将键设置为唯一代码Warning: Each child in a list should have a unique "key" prop.,我的控制台也会为BookListReadingList都提供book.title_id。 ????

javascript json reactjs react-hooks react-component
1个回答
0
投票
export default function BookList ({ books, handleAddBook }) {
return (
    <div>
        {books.map((book) => {
            const onAddBook = () => handleAddBook(book);
            return (
            <>
                <BookDetail key={book.title_id} book={book} />
                <button onClick={onAddBook}>Add to Reading List</button>
            </>
            )
        })}
    </div>
)
}

function App() {

    const [books, setBooks] = useState([])
    const [booksToRead, setBooksToRead] = useState([{ title: 'initialBookToRead', title_id: '1234' }])

    function handleAddBook(book) {
        setBooksToRead([...booksToRead, book])
    }


  return (
    <main>
        <BookList books={books} handleAddBook={handleAddBook}/>
        <ReadingList booksToRead={booksToRead} />
    </main>
  );

}

export default App;

请使用以上组件。您需要将book作为参数传递给handleAddBook。无需存储newBookToRead和useEffect即可使用提及的handleAddBook。

请投票! :)

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