Есть способ сделать array.join в реакции

Я хотел бы добавить разделитель между каждым элементом массива, используя синтаксис типа array.join.

Что-то вроде следующего:

render() {
 let myArray = [1,2,3];
 return (<div>
   {myArray.map(item => <div>{item}</div>).join(<div>|</div>)}
</div>);
}

У меня есть работа с использованием метода lodash.transform, но он кажется уродливым, я хотел бы просто сделать .join(<some-jsx>) и вставить разделитель между каждым элементом.

Ответ 1

Попытка с .join с React Elements, вероятно, не выйдет за вас. Это приведет к результату, который вам нужно описать.

render() {
    let myArray = [1,2,3];
    return (
      <div>
        {myArray.map((item, i, arr) => {
          let divider = i<arr.length-1 && <div>|</div>;
          return (
            <span key={i}>
                <div>{item}</div>
                {divider}
            </span>
          )
        })}
      </div>
    );
  }

Ответ 2

Вы также можете использовать reduce для вставки разделителя между каждым элементом массива:

render() {
  let myArray = [1,2,3];
  return (
    <div>
      {
        myArray
          .map(item => <div>{item}</div>)
          .reduce((acc, x) => acc === null ? [x] : [acc, ' | ', x], null)
      }
    </div>
  );
}

Ответ 3

Btw. вы также можете выполнять функции для реагирования. Моим подходом были бы .forEach пары push(value); push(glue);, а затем pop() конечный клей...

function() {
    joinLike = [];
    originData.forEach(function(v,i) {
        joinLike.push(v);
        joinLike.push(<br>);
    })
    joinLike.pop();
    return joinLike;
}

Ответ 4

reduce здесь избыток, а оптимальная функция - flatMap (map + flatten, иногда называемая concatMap или chain).

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

генерирует что-то вроде

Функция • Тип функции • Функция более высокого порядка • Частичное приложение

P.S.

Для Рамды это R.addIndex(R.chain) вместо flatMap выше.
Для vanilla JS предлагается предложение Stage-2 (atm) для добавления как flatten, так и flatMap: https://tc39.github.io/proposal-flatMap/

Ответ 5

Вы также можете сделать это, комбинируя фрагменты .reduce и React.

function jsxJoin (array, str) {
  return array.length > 0
    ? array.reduce((result, item) => <>{result}{str}{item}</>)
    : null;
}

function jsxJoin (array, str) {
  return array.length > 0
    ? array.reduce((result, item) => <React.Fragment>{result}{str}{item}</React.Fragment>)
    : null;
}

const element = jsxJoin([
  <strong>hello</strong>,
  <em>world</em>
], <span> </span>);

ReactDOM.render(element, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Ответ 6

Чтобы создать запрошенное решение, в React объединение, похоже, не работает, поэтому с картой и сокращением вы можете сделать это следующим образом:

render() {
  let myArray = [1, 2, 3];
  return (
    <div>
        {myArray
            .map(item => <div>{item}</div>)
            .reduce((result, item) => [result, <div>|</div>, item])}
    </div>
  );
}

Ответ 7

Вы также можете попробовать flatMap(). Поддержка браузера идет, но до тех пор вы могли бы использовать polyfill. Единственным недостатком является то, что вам придется потерять последний элемент.

Например.

{myArray.flatMap(item => [<div>{item}</div>, <div>|</div>]).slice(0, -1)}

Или же

{myArray.flatMap((item, i) => [
  <div>{item}</div>,
  i < myArray.length - 1 ? <div>|</div> : null
])

Ответ 8

Вы можете использовать такую функцию, как эта

function componentsJoin(components, separator) {
  return components.reduce(
    (acc, curr) => (acc.length ? [...acc, separator, curr] : [curr]),
    []
  );
}

Или можете использовать пакет, найденный этим https://www.npmjs.com/package/react-join