[英]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.