簡體   English   中英

過濾器 vs 映射 reactjs 和 jsx

[英]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 不會渲染虛假值(只會跳過nullundefined元素)。

第二個示例不會返回相同的結果(一組 React 組件),而是一組純 JavaScript 對象(類型為 book)。 這是因為無論您從過濾器函數返回什么,它都會被轉換為Boolean值 - truefalse並且該值將決定當前元素是否將被過濾。 您的.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} />
    );
  }
  ,[]
)

然而; 我認為使用filtermap可以使代碼更易於閱讀。

我的答案似乎不錯,但我需要使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM