Home > Software design >  How to run a loop inside a jsx string set using dangerouslySetInnerHTML
How to run a loop inside a jsx string set using dangerouslySetInnerHTML

Time:03-18

I am trying to run loop like this

const items = [{name: 'nice'},{ name: 'bice'}, {name: 'tice'}]
 const stringJsx = `
 <ol>
    ${
      items.map((item, index) =>{
        return (
          <li key={index}>this is a nice item : ${item.name}</li>
        )
      })
    }
</ol>
return (
 <>
    
    <h1 id='nice'> this is a nice h1 tag</h1>
    <div dangerouslySetInnerHTML={{ __html: stringJsx }} />
    
 </>
 )
`

I sm [object Object],[object Object],[object Object] as result. How can I run conditions, loop and other things from a jsx as a string?

I need this jsx as string and will be stored in a db.

Thank you.

CodePudding user response:

Since you want it to be a string, you must return a string inside the map(), not a html element, change the stringJsx to something like:

const stringJsx = (`
    <ol>
        ${
            items.map((item, index) => {
                return `<li key=${index}>this is a nice item : ${item.name}</li>`;
            }).join('')
        }
    </ol>
`);

Btw: consider using join('') after the map so there won't be any ,'s in between the <li>'s

Full snippet using the above code:

class Example extends React.Component {    
    render() {

        const items = [{name: 'nice'},{ name: 'bice'}, {name: 'tice'}];
        const stringJsx = (`
            <ol>
                ${
                    items.map((item, index) => {
                        return `<li key=${index}>this is a nice item : ${item.name}</li>`;
                    }).join('')
                }
            </ol>
        `);
        
        return (
            <React.Fragment>
                <h1 id='nice'> this is a nice h1 tag</h1>
                <div dangerouslySetInnerHTML={{ __html: stringJsx }} />
            </React.Fragment>
        )
    }
}

ReactDOM.render(<Example />, document.body);
:root{
    --bg-clr-1: #E7F8F8;
    --card-clr-red: #F03E3E;
    --card-clr-violet: #7950F2;
    --card-clr-green: #12B886;
    --text-clr: #333;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>


Edit:

Another snippet, based on OP's comment, without join(). I've used reduce() to get the same behaviour;

const stringJsx = items.reduce((prev, cur, index) => (
    prev   `<li key=${index}>this is a nice item : ${cur.name}</li>`
), '');

class Example extends React.Component {    
    render() {

        const items = [{name: 'nice'},{ name: 'bice'}, {name: 'tice'}];
        const stringJsx = items.reduce((prev, cur, index) => (
            prev   `<li key=${index}>this is a nice item : ${cur.name}</li>`
        ), '');
        
        return (
            <React.Fragment>
                <h1 id='nice'> this is a nice h1 tag</h1>
                <div dangerouslySetInnerHTML={{ __html: stringJsx }} />
            </React.Fragment>
        )
    }
}

ReactDOM.render(<Example />, document.body);
:root{
    --bg-clr-1: #E7F8F8;
    --card-clr-red: #F03E3E;
    --card-clr-violet: #7950F2;
    --card-clr-green: #12B886;
    --text-clr: #333;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

  • Related