如何使用map和join渲染react组件

Xia*_*ong 77 reactjs

我有一个组件将显示字符串数组.代码看起来像这样.

React.createClass({
  render() {
     <div>
        this.props.data.map(t => <span>t</span>)
     </div>
  }
})
Run Code Online (Sandbox Code Playgroud)

它工作得非常好.即如果props.data = ['tom','jason','chris'] 页面中的渲染结果将是tomjasonchris

然后,我想使用逗号加入所有名称,所以我将代码更改为

this.props.data.map(t => <span>t</span>).join(', ')
Run Code Online (Sandbox Code Playgroud)

但是,渲染结果是[Object],[Object],[Object].

我不知道如何解释对象成为要呈现的反应组件.有什么建议吗?

Maa*_*rst 115

通过不给出第二个参数来减少和不扩展先前的结果,可以使最佳答案更简单,更优雅:

class List extends React.Component {
  render() {
     <div>
        {this.props.data
          .map(t => <span>{t}</span>)
          .reduce((prev, curr) => [prev, ', ', curr])}
     </div>
  }
}
Run Code Online (Sandbox Code Playgroud)

没有第二个参数,reduce()将从索引1而不是0开始,并且React对嵌套数组非常满意.

如评论中所述,您只想将此用于具有至少一个项目的数组,因为reduce()没有第二个参数将抛出一个空数组.通常情况下这不应该是一个问题,因为你想要显示一个自定义消息,说明空数组的"这是空的".

  • 还要注意,这会递归地嵌套`prev`数组.例如`[1,2,3,4]`变为`[[[1,",",2],",",3],",",4]`. (5认同)
  • `如果数组为空且未提供初始值,则会抛出 TypeError。`。所以它不适用于空数组。 (4认同)
  • @Tamlyn:你认为我在答案中提到你的观点('React对嵌套数组非常满意')是否足够清楚或者我应该详细说明这一点? (2认同)
  • 有人让这个解决方案与 React + TypeScript 一起使用吗? (2认同)

dev*_*snd 24

您可以使用reduce组合数组的多个元素:

React.createClass({
  render() {
     <div>
        this.props.data
        .map(t => <span>t</span>)
        .reduce((accu, elem) => {
            return accu === null ? [elem] : [...accu, ',', elem]
        }, null)
     </div>
  }
})
Run Code Online (Sandbox Code Playgroud)

这会使累加器初始化为null,因此我们可以将第一个项目包装在一个数组中.对于数组中的每个后续元素,我们构造一个新数组,其中包含使用的所有先前元素...-operator,添加分隔符,然后添加下一个元素.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

  • @Larry如果删除null check和ternary,并将[]作为初始化程序传递,你如何避免使用逗号?`['a'].reduce((a,e)=> [... a,',',e],[])`产生`[",","a"]`.除非数组为空,否则不传递初始化程序,在这种情况下它返回TypeError. (6认同)
  • 谢谢,正是我需要的.您可以通过将累加器初始化为空数组来删除空检查和三元组 (2认同)

Cas*_*mir 11

如果我只想渲染一个逗号分隔的组件数组,我通常会觉得reduce太冗长了。在这种情况下更短的解决方案是

{arr.map((item, index) => (
  <Fragment key={item.id}>
    {index > 0 && ', '}
    <Item {...item} />
  </Fragment>
))}
Run Code Online (Sandbox Code Playgroud)

{index > 0 && ', '} 将在除第一个之外的所有数组项前面呈现一个逗号,后跟一个空格。

如果你想用其他东西分隔倒数第二个项目和最后一个项目,比如 string ' and ',你可以替换{index > 0 && ', '}

{arr.map((item, index) => (
  <Fragment key={item.id}>
    {index > 0 && ', '}
    <Item {...item} />
  </Fragment>
))}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个,对于像我这样的 React 新手来说,这个解决方案最容易理解:) (2认同)

Pit*_*ith 8

使用React 16进行更新:现在允许直接渲染字符串,因此您可以通过删除所有无用的<span>标记来简化代码.

const List = ({data}) => data.reduce((prev, curr) => [prev, ', ', curr])
Run Code Online (Sandbox Code Playgroud)


Fen*_*1kz 7

我的变体:

{this.props.data
    .map(item => <span>{item}</span>)
    .map((item, index) => [index > 0 && ', ', item ])}
Run Code Online (Sandbox Code Playgroud)


oob*_*gam 6

<span>{t}</span>你返回是一个对象,而不是字符串.查看有关它的反应文档https://facebook.github.io/react/docs/jsx-in-depth.html#the-transform

通过.join()在返回的数组上使用map,您将加入对象数组.[object Object], ...

您可以将逗号放在内部,<span></span>以便按照您希望的方式呈现.

  render() {
    return (
      <div>
        { this.props.data.map(
            (t,i) => <span>{t}{ this.props.data.length - 1 === i ? '' : ','} </span>
          )
        }
      </div>
    )
  }
Run Code Online (Sandbox Code Playgroud)

示例: https ://jsbin.com/xomopahalo/edit?html,js,output


Jst*_*uff 6

接受的答案实际上返回一个数组数组,因为prev每次都是一个数组.React足够聪明,可以使这个工作,但是它很容易在将来引起问题,例如在为每个map结果提供键时打破Reacts diffing算法.

React.Fragment功能允许我们以易于理解的方式执行此操作,而不会出现根本问题.

class List extends React.Component {
  render() {
     <div>
        {this.props.data
          .map((t, index) => 
            <React.Fragment key={index}>
              <span> {t}</span> ,
            </React.Fragment>
          )
      </div>
  }
}
Run Code Online (Sandbox Code Playgroud)

随着React.Fragment我们可以简单地将分离器,的返回的HTML之外并做出反应不会抱怨.

  • 很棒的解决方案,但您需要删除数组最后一个元素的逗号 (5认同)
  • 您可以通过此修改删除最后一个逗号: &lt;React.Fragment key={index}&gt; &lt;span&gt; {t}&lt;/span&gt; {index === this.props.data.length - 1 ? '' : ','} &lt;/React.Fragment&gt; (3认同)
  • @JohnP将其添加在前面更容易: `&lt;React.Fragment key={index}&gt;{index ? ',' : ''}&lt;span&gt;{t}&lt;/span&gt;&lt;/React.Fragment&gt;`。 (3认同)