You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React项目中map与filter渲染差异及报错原因咨询

为什么React中用filter遍历会报错,而map不会?

这问题核心是没搞清楚数组方法mapfilter职责完全不同,不是React的map有什么特殊,而是你用错了filter的用法~

先看你用map的逻辑为什么没问题

Array.prototype.map的作用是转换数组中的每一个元素:它会遍历数组,把每个元素传入回调函数,然后把回调的返回值收集起来,组成一个新数组。

你的map回调里,当book.shelf === shelf时返回<Book />组件,否则默认返回undefined(因为if分支外没return)。最终你得到的是一个包含<Book />组件和少量undefined的数组,而React会自动忽略数组中的undefinednull这类无效子元素,所以能正常渲染。

再看filter为什么会报错

Array.prototype.filter的作用是筛选数组元素:它的回调函数需要返回一个布尔值(true/false),用来决定当前元素是否保留在新数组里。

但你在filter的回调里做了什么?你返回的是<Book />组件——这本质是一个React元素对象。JavaScript里,所有对象在布尔上下文里都会被判定为true,所以不管book.shelf是否等于shelf,你的回调都会返回true(因为组件对象是truthy的)。最终filter返回的数组是books数组里的所有book对象,然后你把这个对象数组传给React渲染,自然就会报错:Objects are not valid as a React child——React不能直接渲染普通的JavaScript对象。

正确的用法:先筛选再转换

如果你想先筛选出符合条件的book,再渲染组件,应该把filtermap结合起来用:

<ol className="books-grid">
  { books && books
      .filter(book => book.shelf === shelf)
      .map((book, index) => (
        <Book 
          key={book.id || index} 
          changeShelf={this.props.changeShelf} 
          book={book} 
        />
      ))
  }
</ol>

这里filter先筛选出shelf匹配的book对象,然后map把这些对象转换成<Book />组件数组,React就能正常渲染了。

补充:React对数组渲染的要求

React确实可以直接渲染数组,但数组里的元素必须是有效的React子元素(比如React组件、字符串、数字、null/undefined等),而普通的JavaScript对象是不行的——这也是你用filter时触发错误的直接原因。

内容的提问来源于stack exchange,提问作者HelloWorld

火山引擎 最新活动