[英]filter vs map reactjs and jsx
我正在做一個反應項目來學習反應。
在組件的渲染方法中,當我使用.map
迭代值並返回組件數組時,一切都按預期工作。
<ol className="books-grid">
{
books && books.map((book, index) => {
if (book.shelf === shelf) {
return (
<Book key={book && book.id ? book.id : index} changeShelf={this.props.changeShelf} book={book} />
);
}
})}
</ol>
但是當我使用filter
:
<ol className="books-grid">
{
books && books.filter((book, index) => {
if (book.shelf === shelf) {
return (
<Book key={book && book.id ? book.id : index} changeShelf={this.props.changeShelf} book={book} />
);
}
})}
</ol>
我收到錯誤(我已經研究過)
Uncaught (in promise) Error: Objects are not valid as a React child
我不明白為什么filter
會拋出這個錯誤 vs map
? react 和.map
有什么獨特之處嗎? 兩者都返回一個數組。
Array.filter
不允許您將數據轉換為組件。 這就是Array.map
的工作。
您應該先過濾,然后鏈接 map 調用:
{
books && books
.filter(book => book.shelf === shelf)
.map((book, index) => {
return (
<Book
key={book && book.id ? book.id : index}
changeShelf={this.props.changeShelf}
book={book} />
);
})
}
如果你想避免第二次遍歷你的books
列表,你也可以返回null
,盡管這“不太好”,因為當 React 根本不需要做任何工作時,你會強制它呈現null
:
{
books && books
.map((book, index) => {
if (book.shelf !== shelf) {
return null;
}
return (
<Book
key={book && book.id ? book.id : index}
changeShelf={this.props.changeShelf}
book={book} />
);
})
}
React 和map()
或filter()
沒有什么獨特之處。
在使用map()
的第一個示例中,您將返回一個在 DOM 中呈現的 React 組件數組。 您正在將數組中的每個普通 JavaScript 對象轉換(映射)為 React 組件。 事實上,如果條件book.shelf === shelf
為假,您還將在結果數組中返回一些undefined
元素。 您的數組可能看起來像[<Book />, <Book />, undefined, <Book />, undefined]
。 這沒什么大不了的,因為 React 不會渲染虛假值(只會跳過null
或undefined
元素)。
第二個示例不會返回相同的結果(一組 React 組件),而是一組純 JavaScript 對象(類型為 book)。 這是因為無論您從過濾器函數返回什么,它都會被轉換為Boolean
值 - true
或false
並且該值將決定當前元素是否將被過濾。 您的.filter()
函數的結果將是這樣的(想象一下shelf === 'Science'
):
Original array: [{ shelf: "Science" }, { shelf: "Thrillers" }, { shelf: "Informatics" }]
Filtered array: [{ shelf: "Science" }]
如您所見,數組中的項目不會是 React 組件( <Book />
)並且 React 將無法在 DOM 中呈現它們,因此會引發錯誤。
如果您只想對數組使用一次傳遞,則可以使用 reduce:
books && books
.reduce(
(all,book, index) => {
if (book.shelf !== shelf) {
return all;
}
return all.concat(
<Book
key={book && book.id ? book.id : index}
changeShelf={this.props.changeShelf}
book={book} />
);
}
,[]
)
然而; 我認為使用filter
和map
可以使代碼更易於閱讀。
我的答案似乎不錯,但我需要使用includes()
才能工作,使用toLowerCase()
也可能是個好主意:
{
books && books
.filter(book => book.shelf.toLowerCase().includes(shelf.toLowerCase()))
.map((book, index) => {
return (
<Book
key={book && book.id ? book.id : index}
changeShelf={this.props.changeShelf}
book={book} />
);
})
}
我也面臨同樣的錯誤。 然后,我還將我的map
方法包裝在filter
方法上,這有助於我解決錯誤並將其作為反應有效子項接受。
<ul className="menu">
{navigationLinks?.filter((eachNavigation) => {
if (eachNavigation.select.length < 1) {
return eachNavigation;
}
}).map((eachNavigation, index) => {
return (
<li key={index} className="menu__list menu__list--noSelect">
<a href={eachNavigation.link}>{eachNavigation.title}</a>
</li>
)
})
}
</ul>
<ul className="menu"> {navigationLinks?.filter((eachNavigation) => { if (eachNavigation.select.length < 1) { return eachNavigation; } }).map((eachNavigation, index) => { return ( <li key={index} className="menu__list menu__list--noSelect"> <a href={eachNavigation.link}>{eachNavigation.title}</a> </li> ) }) } </ul>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.