I've written some code to render repeating elements in ReactJS, but I hate how ugly it is.
render: function(){   var titles = this.props.titles.map(function(title) {     return <th>{title}</th>;   });   var rows = this.props.rows.map(function(row) {     var cells = [];     for (var i in row) {       cells.push(<td>{row[i]}</td>);     }     return <tr>{cells}</tr>;   });   return (     <table className="MyClassName">       <thead>         <tr>{titles}</tr>       </thead>       <tbody>{rows}</tbody>     </table>   ); }    Is there a better way to achieve this?
(I would like to embed for loops within the template code, or some similar approach.)
render() should return single element. You can split it up and have multiple components which implement some dedicated logic which is better and used to be a good practice in React.
In the ReactDOM. render you still can't render multiple items because react needs a root. So you can render a single component inside the ReactDOM. render and render an array of items in the internal component.
You can put expressions inside braces. Notice in the compiled JavaScript why a for loop would never be possible inside JSX syntax; JSX amounts to function calls and sugared function arguments. Only expressions are allowed.
(Also: Remember to add key attributes to components rendered inside loops.)
JSX + ES2015:
render() {   return (     <table className="MyClassName">       <thead>         <tr>           {this.props.titles.map(title =>             <th key={title}>{title}</th>           )}         </tr>       </thead>       <tbody>         {this.props.rows.map((row, i) =>           <tr key={i}>             {row.map((col, j) =>               <td key={j}>{col}</td>             )}           </tr>         )}       </tbody>     </table>   ); }    JavaScript:
render: function() {   return (     React.DOM.table({className: "MyClassName"},        React.DOM.thead(null,          React.DOM.tr(null,            this.props.titles.map(function(title) {             return React.DOM.th({key: title}, title);           })         )       ),        React.DOM.tbody(null,          this.props.rows.map(function(row, i) {           return (             React.DOM.tr({key: i},                row.map(function(col, j) {                 return React.DOM.td({key: j}, col);               })             )           );         })       )     )   ); }  
                        Since Array(3) will create an un-iterable array, it must be populated to allow the usage of the map Array method. A way to "convert" is to destruct it inside Array-brackets, which "forces" the Array to be filled with undefined values, same as Array(N).fill(undefined)
<table>     { [...Array(3)].map((_, index) => <tr key={index}/>) } </table>  fill():<table>     { Array(3).fill(<tr/>) } </table>  ⚠️ Problem with above example is the lack of
keyprop, which is a must.
(Using an iterator'sindexaskeyis not recommended)
const tableSize = [3,4] const Table = (     <table>         <tbody>         { [...Array(tableSize[0])].map((tr, trIdx) =>              <tr key={trIdx}>                { [...Array(tableSize[1])].map((a, tdIdx, arr) =>                    <td key={trIdx + tdIdx}>                   {arr.length * trIdx + tdIdx + 1}                   </td>                )}             </tr>         )}         </tbody>     </table> );  ReactDOM.render(Table, document.querySelector('main'))  td{ border:1px solid silver; padding:1em; }  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <main></main>  If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With