首页 文章

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

提问于
浏览
64

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

React.createClass({
  render() {
     <div>
        this.props.data.map(t => <span>t</span>)
     </div>
  }
})

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

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

this.props.data.map(t => <span>t</span>).join(', ')

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

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

9 回答

  • 6

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

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

    没有第二个参数, reduce()start at index 1而不是0,并且React对嵌套数组非常满意 .

    如评论中所述,您只想将此用于具有至少一个项目的数组,因为没有第二个参数的 reduce() 将使用空数组 . 通常这不应该是一个问题,因为你想显示一个自定义消息,无论如何都要为空数组显示像'this is empty'这样的东西 .

  • 16

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

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

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

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

  • 87

    Update with React 16: 现在允许直接呈现字符串,因此您可以通过删除所有无用的 <span> 标记来简化代码 .

    const List = ({data}) => data.reduce((prev, curr) => [prev, ', ', curr])
    
  • 1

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

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

    您可以将逗号放在 <span></span> 中,以便以您希望的方式呈现它 .

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

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

  • 5

    接受的答案实际上返回一个数组数组,因为 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>
      }
    }
    

    使用 React.Fragment ,我们可以简单地将分隔符 , 放在返回的HTML之外,并且React不会抱怨 .

  • 3

    我的变种:

    {this.props.data
        .map(item => <span>{item}</span>)
        .map((item, index) => [index > 0 && ', ', item ])}
    
  • 1

    使用嵌套数组在外面保持“,” .

    <div>
          {this.props.data.map((element, index) => index == this.props.data.length - 1 ? <span key={index}>{element}</span> : [<span key={index}>{element}</span>, ", "])}
      </div>
    

    通过将数据保存到数组并修改最后一个元素而不是一直检查其最后一个元素来优化它 .

    let processedData = this.props.data.map((element, index) => [<span key={index}>{element}</span>, ", "])
      processedData [this.props.data.length - 1].pop()
      <div>
          {processedData}
      </div>
    
  • 5

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

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

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

    如果你想把倒数第二个项目与最后一个项目分开,比如字符串 ' and ' ,你可以用 {index > 0 && ', '} 替换

    {index > 0 && index !== arr.length - 1 && ', '}
    {index === arr.length - 1 && ' and '}
    
  • 0

    这对我有用:

    {data.map( ( item, i ) => {
                      return (
                          <span key={i}>{item.propery}</span>
                        )
                      } ).reduce( ( prev, curr ) => [ prev, ', ', curr ] )}
    

相关问题