我想使用类似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>)
并让它在每个项目之间插入一个分隔符。
答案 0 :(得分:7)
尝试使用React Elements加入.join可能并不适合你。这将产生您描述的结果。
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>
);
}
答案 1 :(得分:6)
您还可以使用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>
);
}
或使用片段:
render() {
let myArray = [1,2,3];
return (
<div>
{
myArray
.map(item => <div>{item}</div>)
.reduce((acc, x) => acc === null ? x : <>{acc} | {x}</>, null)
}
</div>
);
}
答案 2 :(得分:2)
顺便说一下。你也可以提供反应的功能。我的方法是.forEach
对push(value); push(glue);
,之后是pop()
尾随胶......
function() {
joinLike = [];
originData.forEach(function(v,i) {
joinLike.push(v);
joinLike.push(<br>);
})
joinLike.pop();
return joinLike;
}
答案 3 :(得分:1)
您还可以通过组合.reduce
和React
fragments来做到这一点。
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>
答案 4 :(得分:1)
使用Array.map
和React.Fragment
可以将每个数组项与所需的任何JSX元素连接在一起。在下面的示例中,我使用的是<br />
标记,但是可以替换为所需的任何元素。
const lines = ['line 1', 'line 2', 'line 3'];
lines.map((l, i) => (
<React.Fragment key={i}>{l}{i < (lines.length - 1) ? <br /> : ''}</React.Fragment>
));
输出应为
line 1 <br />
line 2 <br />
line 3
答案 5 :(得分:0)
要生成所需的解决方案,在React联接中似乎不起作用,因此使用map和reduce可以这样做:
render() {
let myArray = [1, 2, 3];
return (
<div>
{myArray
.map(item => <div>{item}</div>)
.reduce((result, item) => [result, <div>|</div>, item])}
</div>
);
}
答案 6 :(得分:0)
您也可以尝试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
])
答案 7 :(得分:0)
您可以使用类似这样的功能
function componentsJoin(components, separator) {
return components.reduce(
(acc, curr) => (acc.length ? [...acc, separator, curr] : [curr]),
[]
);
}
或者可以用一个包,发现这个 https://www.npmjs.com/package/react-join
答案 8 :(得分:0)
如果您使用的是 TypeScript,您可以简单地复制此文件并使用 jsxJoin
:
import { Fragment } from "react";
/**
* Join together a set of JSX elements with a separator.
*
* @see https://stackoverflow.com/q/33577448/5506547
*/
function jsxJoin(components: JSX.Element[], separator: any) {
// Just to be sure, remove falsy values so we can add conditionals to the components array
const filtered = components.filter(Boolean);
return filtered.length === 0
? null
: (filtered.reduce(
(acc, curr, i) =>
acc.length
? [
...acc,
// Wrap the separator in a fragment to avoid `missing key` issues
<Fragment key={i}>{separator}</Fragment>,
curr
]
: [curr],
[]
) as JSX.Element[]);
}
export { jsxJoin };
答案 9 :(得分:0)
// typescript
export function joinArray<T, S>(array: Array<T>, separator: S): Array<T | S> {
return array.reduce<(T | S)[]>((p, c, idx) => {
if (idx === 0) return [c];
else return [...p, separator, c];
}, []);
}
// javascript
export function joinArray(array, separator) {
return array.reduce((p, c, idx) => {
if (idx === 0)
return [c];
else
return [...p, separator, c];
}, []);
}
// example
console.log(joinArray(["1", "2", "3"], 2));
// -> ["1", 2, "2", 2, "3"]
// example
// privacyViews -> JSX.Element[]
const privacyViews = joinArray(
privacys.value.map(({ key, name }) => {
return (
<button onClick={() => clickPrivacy(key!)} class={Style.privacyBtn}>
{name}
</button>
);
}),
<span class={Style.privacyBtn}>、</span>
);