I just wanted to share a little snippet that took me a few minutes to write but that is really useful. Let’s say you want to display a list of items separated by a string, or a line break. There are lots of options here: https://stackoverflow.com/questions/34034038/how-to-render-react-components-by-using-map-and-join but they are not very elegant.
How about if you could write something like:
1 2 3 4 5 |
function render({ products }) { return Utils.mapWithSeparator(products, <br/>, product => <a href={"/Product/Details?id=" + product.id}>{product.description}</a> ); } |
and get a list of links, separated by line breaks?
Well you can. Here is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
static mapWithSeparator<T>(source: Iterable<T>, separator: ReactNode, mapfn: (x: T) => ReactNode) { const result: ReactNode[] = []; const iter = source[Symbol.iterator](); let { value: current, done: done } = iter.next(); if (done) return result; let last = current; ({ value: current, done: done } = iter.next()); let i = isValidElement(separator) ? 0 : undefined; while (!done) { result.push(mapfn(last)); if (i !== undefined) result.push(cloneElement(separator as ReactElement, { key: "sep_" + i++ })); else result.push(separator); last = current; ({ value: current, done: done } = iter.next()); } result.push(mapfn(last)); return result; } |
There are simpler ways of writing this but I wanted to understand how iterators work.