web-dev-qa-db-ja.com

リンクのコンマ区切りリストのレンダリング

私はコンマ区切りのリンクのリストを出力しようとしていますが、これが私の解決策です。

var Item = React.createComponent({
  render: function() {

    var tags = [],
        tag;

    for (var i = 0, l = item.tags.length; i < l; i++) {
      if (i === item.tags.length - 1) {
        tag = <span><Tag key={i} tag={item.tags[i]} /></span>;
      } else {
        tag = <span><Tag key={i} tag={item.tags[i]} /><span>, </span></span>;
      }
      tags.Push(tag);
    }

    return (
      <tr>
        <td>
          {item.name}
        </td>
        <td>
          {tags}
        </td>
      </tr>
    );

  }
});

私はこれを達成するためのより良い、よりクリーンな方法があるのか​​と思っていましたか?

ありがとう

38
Nick

カーンアカデミーでは、intersperseというヘルパーを使用します。

/* intersperse: Return an array with the separator interspersed between
 * each element of the input array.
 *
 * > _([1,2,3]).intersperse(0)
 * [1,0,2,0,3]
 */
function intersperse(arr, sep) {
    if (arr.length === 0) {
        return [];
    }

    return arr.slice(1).reduce(function(xs, x, i) {
        return xs.concat([sep, x]);
    }, [arr[0]]);
}

次のようなコードを記述できます。

var tags = item.tags.map(function(tag, i) {
    return <Tag key={i} tag={item.tags[i]} />;
};
tags = intersperse(tags, ", ");
64
Sophie Alpert

単純に

{tags.map((tag, i) => <span key={i}>
    {i > 0 && ", "}
    <Tag tag={tag} />
</span>)}


React 16では、さらに簡単に行うことができます。

{tags.map((tag, i) => [
    i > 0 && ", ",
    <Tag key={i} tag={tag} />
])}
63
imos

または、単にリスト項目を順序付けられていないリストに書き込んで、CSSを使用します。

var Item = React.createComponent({
  render: function() {

    var tags = this.props.item.tags.map(function(i, item) {
      return <li><Tag key={i} tag={item} /></li>
    });

    return (
      <tr>
        <td>
          {this.props.item.name}
        </td>
        <td>
          <ul className="list--tags">
            {tags}
          </ul>
        </td>
      </tr>
    );

  }
});

そしてCSS:

.list--tags {
    padding-left: 0;
    text-transform: capitalize;
}

.list--tags > li {
    display: inline;
}

.list--tags > li:before {
    content:',\0000a0'; /* Non-breaking space */
}
.list--tags > li:first-child:before {
    content: normal;
}
8
i_like_robots
import React from 'react';
import { compact } from 'lodash';

// Whatever you want to separate your items with commas, space, border...
const Separator = () =>  { ... }; 

// Helpful component to wrap items that should be separated
const WithSeparators = ({ children, ...props }) => {

  // _.compact will remove falsey values: useful when doing conditional rendering
  const array = compact(React.Children.toArray(children));

  return array.map((childrenItem, i) => (
    <React.Fragment key={`${i}`}>
      {i > 0 && <Separator {...props} />}
      {childrenItem}
    </React.Fragment>
  ));
};

const MyPage = () => (
  <WithSeparators/>
    <div>First</div>
    {second && (<div>Maybe second</div>)}
    {third && (<div>Maybe third</div>)}
    <div>Fourth</div>
  </WithSeparators>
);
2

<span>sおよび<br>sとジャンクをセパレーターとして許可するソリューションは次のとおりです。

const createFragment = require('react-addons-create-fragment');

function joinElements(arr,sep=<br/>) {
    let frag = {};
    for(let i=0,add=false;;++i) {
        if(add) {
            frag[`sep-${i}`] = sep;
        }
        if(i >= arr.length) {
            break;
        }
        if(add = !!arr[i]) {
            frag[`el-${i}`] = arr[i];
        }
    }
    return createFragment(frag);
}

また、誤った配列要素も除外されます。これを使用して、いくつかの住所フィールドに入力されていない住所をフォーマットしました。

欠けているキーに関する警告を回避するためにフラグメントを使用します。

1
mpen

トリックを行う関数コンポーネント。 @imosの応答に触発されました。 React 16.で機能します。

const Separate = ({ items, render, separator = ', ' }) =>
  items.map((item, index) =>
    [index > 0 && separator, render(item)]
  )

<Separate
  items={['Foo', 'Bar']}
  render={item => <Tag tag={item} />}
/>
1
Alberto Jacini

追加のタグなしのソリューション

reduceはここではやりすぎです。使用する最適な関数は(技術的に)flatMap(またはRamdaではchain)です。残念ながら、JSは(まだ)提供していません。

_<p className="conceps inline list">
  {flatMap((concept, i) =>
    [concept, <span key={i} className="separator">&#8226;</span>]
  , lesson.concepts).slice(-1)}
</p>
_

のようなものを生成します

関数•関数タイプ•高階関数•部分適用

追伸.

ramdaの場合、上記のflatMapではなくR.addIndex(R.chain)です。

0
Ivan Kleshnin

最も簡単な方法

    const elementsArr = ["a","b,"c"];
    let elementsToRender = [] ;
    elementsArr.forEach((element, index) => {
        let elementComponent = <TAG className="abc" key={element.id}>{element}</TAG>
        elementsToRender.Push(elementComponent);
        if(index !== (elementsArr.length - 1)){
            elementsToRender.Push(", ");
        }
    });

    render(){
        return (
            <div>{elementsToRender}</div>
        )
    }
0
pareshm

上記の素晴らしい答えに加えて、ラムダには intersperse があります。

あなたができるアイテムの束をコンマで区切るには:

const makeLinks = (x: Result[]) =>
  intersperse(<>,</>, map(makeLink, x))

かなり簡潔

0
Damian Green

単純なもの:

{items.map((item, index) => (
    <span key={item.id}>
      {item.id}
      {index < items.length - 1 && ', '}
    </span>
 ))}
0