如何使用map和join

时间:2015-12-02 02:50:10

标签: reactjs

我有一个组件将显示String of String。代码看起来像这样。

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

它工作得非常好。 即如果 props.data = [&#39; tom&#39;,&#39; jason&#39;,&#39; chris&#39;] 页面中的渲染结果将是< EM> tomjasonchris

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

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

但是,渲染的结果是 [Object],[Object],[Object]。

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

16 个答案:

答案 0 :(得分:92)

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

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()将使用空数组。通常这不应该是一个问题,因为你想显示一个自定义消息,说明这样的事情是空的&#39;无论如何,对于空阵列。

答案 1 :(得分:18)

您可以使用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

答案 2 :(得分:6)

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

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

答案 3 :(得分:5)

您要返回的<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>
    )
  }

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

答案 4 :(得分: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就不会抱怨。

答案 5 :(得分:3)

我的变体:

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

答案 6 :(得分: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>

答案 7 :(得分:1)

如果我只想呈现逗号分隔的组件数组,通常会发现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 '}

答案 8 :(得分:0)

这对我有用:

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

答案 9 :(得分:0)

As mentioned by Pith,React 16允许您直接使用字符串,因此不再需要将字符串包装在span标签中。以Maarten's answer为基础,如果您还想立即处理自定义消息(并避免在空数组上引发错误),则可以在数组的length属性上使用三元if语句来引导操作。可能看起来像这样:

class List extends React.Component {
  const { data } = this.props;

  render() {
     <div>
        {data.length
          ? data.reduce((prev, curr) => [prev, ', ', curr])
          : 'No data in the array'
        }
     </div>
  }
}

答案 10 :(得分:0)

这应该返回一个平面数组。通过提供初始的空数组来处理具有不可迭代的第一个对象的情况,并从结果中过滤不需要的第一个逗号

[{}, 'b', 'c'].reduce((prev, curr) => [...prev, ', ', curr], []).splice(1) // => [{}, 'b', 'c']

答案 11 :(得分:0)

使用es6,您可以执行以下操作:

strings

然后运行:

const joinComponents = (accumulator, current) => [
  ...accumulator, 
  accumulator.length ? ', ' : '', 
  current
]

答案 12 :(得分:0)

我是唯一认为这里的答案中有很多不必要的散布和嵌套的人吗?简明扼要的观点是肯定的,但是这为规模问题或React改变了它们处理嵌套数组/片段的方式留有余地。

const joinJsxArray = (arr, joinWith) => {
  if (!arr || arr.length < 2) { return arr; }

  const out = [arr[0]];
  for (let i = 1; i < arr.length; i += 1) {
    out.push(joinWith, arr[i]);
  }
  return out;
};

// render()
<div>
  {joinJsxArray(this.props.data.map(t => <span>t</span>), ', ')}
</div>

一个数组,没有嵌套。也没有性感的方法链接,但是,如果您经常这样做,则可以始终将其添加到数组原型中,或将其包装在需要映射回调的函数中,以一次性完成所有操作。

答案 13 :(得分:0)

function YourComponent(props) {

  const criteria = [];

  if (something) {
    criteria.push(<strong>{ something }</strong>);
  }

  // join the jsx elements with `, `
  const elements = criteria.reduce((accu, elem) => {
    return accu === null ? [elem] : [...accu, ', ', elem]
  }, null);

  // render in a jsx friendly way
  return elements.map((el, index) => <React.Fragment key={ index }>{ el }</React.Fragment> );

}

答案 14 :(得分:0)

从React 17开始,您可以简单地:

<div>
  {[1, 2, 3].map((e, i) => <p key={i}>{e}</p>)}
</div>

它将呈现为:

<div>
  <p>1</p>
  <p>2</p>
  <p>3</p>
</div>

答案 15 :(得分:0)

只需在 map 之后添加 join() 并将其放入标签中:

<span>{this.props.data.map((item) => item).join(', ')}</span>