Using JSX in this.state but it gets rendered as plain text












1















I am dynamically rendering a list of elements. Depending on key-value pairs in those elements, I need to insert other elements in front of them.



I'd like to use <sup></sup> tags on those elements, but they are showing as plain text instead of superscript.



How can I use JSX in the state which is an array of strings and not have it come out as plain text?



The line in question is this one: allOptions.splice(index, 0, this.props.levelNames[j]);



The prop would be : [...., '1<sup>st</sup> Level',...]



But when rendered it just comes out as plain text.



import React, { Component } from 'react';
import './App.css';

export class Chosen extends Component {
render() {
let allOptions = this.props.chosenSpells.map((val, i) => this.props.selectMaker(val, i, 'chosen'));


let index;
let headings=this.props.levelNames;

for (let j=this.props.highestSpellLevel; j>0;j--) {
index = this.props.chosenSpells.findIndex(function findLevel (element) {return element.level==j});
console.log(index);
console.log(headings[j]);
if (index>=0){
allOptions.splice(index, 0, this.props.levelNames[j]);
}
}

return (
<div>
<b><span className="choose">Chosen (click to remove):</span></b><br/>
<div className="my-custom-select">
{allOptions}
</div>
</div>
);
}
}


export class Parent extends Component {

constructor(props) {
super(props);

this.state = {
levelNames: ['Cantrips', '1<sup>st</sup> Level', '2nd Level', '3rd Level']
};









share|improve this question



























    1















    I am dynamically rendering a list of elements. Depending on key-value pairs in those elements, I need to insert other elements in front of them.



    I'd like to use <sup></sup> tags on those elements, but they are showing as plain text instead of superscript.



    How can I use JSX in the state which is an array of strings and not have it come out as plain text?



    The line in question is this one: allOptions.splice(index, 0, this.props.levelNames[j]);



    The prop would be : [...., '1<sup>st</sup> Level',...]



    But when rendered it just comes out as plain text.



    import React, { Component } from 'react';
    import './App.css';

    export class Chosen extends Component {
    render() {
    let allOptions = this.props.chosenSpells.map((val, i) => this.props.selectMaker(val, i, 'chosen'));


    let index;
    let headings=this.props.levelNames;

    for (let j=this.props.highestSpellLevel; j>0;j--) {
    index = this.props.chosenSpells.findIndex(function findLevel (element) {return element.level==j});
    console.log(index);
    console.log(headings[j]);
    if (index>=0){
    allOptions.splice(index, 0, this.props.levelNames[j]);
    }
    }

    return (
    <div>
    <b><span className="choose">Chosen (click to remove):</span></b><br/>
    <div className="my-custom-select">
    {allOptions}
    </div>
    </div>
    );
    }
    }


    export class Parent extends Component {

    constructor(props) {
    super(props);

    this.state = {
    levelNames: ['Cantrips', '1<sup>st</sup> Level', '2nd Level', '3rd Level']
    };









    share|improve this question

























      1












      1








      1








      I am dynamically rendering a list of elements. Depending on key-value pairs in those elements, I need to insert other elements in front of them.



      I'd like to use <sup></sup> tags on those elements, but they are showing as plain text instead of superscript.



      How can I use JSX in the state which is an array of strings and not have it come out as plain text?



      The line in question is this one: allOptions.splice(index, 0, this.props.levelNames[j]);



      The prop would be : [...., '1<sup>st</sup> Level',...]



      But when rendered it just comes out as plain text.



      import React, { Component } from 'react';
      import './App.css';

      export class Chosen extends Component {
      render() {
      let allOptions = this.props.chosenSpells.map((val, i) => this.props.selectMaker(val, i, 'chosen'));


      let index;
      let headings=this.props.levelNames;

      for (let j=this.props.highestSpellLevel; j>0;j--) {
      index = this.props.chosenSpells.findIndex(function findLevel (element) {return element.level==j});
      console.log(index);
      console.log(headings[j]);
      if (index>=0){
      allOptions.splice(index, 0, this.props.levelNames[j]);
      }
      }

      return (
      <div>
      <b><span className="choose">Chosen (click to remove):</span></b><br/>
      <div className="my-custom-select">
      {allOptions}
      </div>
      </div>
      );
      }
      }


      export class Parent extends Component {

      constructor(props) {
      super(props);

      this.state = {
      levelNames: ['Cantrips', '1<sup>st</sup> Level', '2nd Level', '3rd Level']
      };









      share|improve this question














      I am dynamically rendering a list of elements. Depending on key-value pairs in those elements, I need to insert other elements in front of them.



      I'd like to use <sup></sup> tags on those elements, but they are showing as plain text instead of superscript.



      How can I use JSX in the state which is an array of strings and not have it come out as plain text?



      The line in question is this one: allOptions.splice(index, 0, this.props.levelNames[j]);



      The prop would be : [...., '1<sup>st</sup> Level',...]



      But when rendered it just comes out as plain text.



      import React, { Component } from 'react';
      import './App.css';

      export class Chosen extends Component {
      render() {
      let allOptions = this.props.chosenSpells.map((val, i) => this.props.selectMaker(val, i, 'chosen'));


      let index;
      let headings=this.props.levelNames;

      for (let j=this.props.highestSpellLevel; j>0;j--) {
      index = this.props.chosenSpells.findIndex(function findLevel (element) {return element.level==j});
      console.log(index);
      console.log(headings[j]);
      if (index>=0){
      allOptions.splice(index, 0, this.props.levelNames[j]);
      }
      }

      return (
      <div>
      <b><span className="choose">Chosen (click to remove):</span></b><br/>
      <div className="my-custom-select">
      {allOptions}
      </div>
      </div>
      );
      }
      }


      export class Parent extends Component {

      constructor(props) {
      super(props);

      this.state = {
      levelNames: ['Cantrips', '1<sup>st</sup> Level', '2nd Level', '3rd Level']
      };






      javascript reactjs jsx






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 1 at 8:52









      KingVKingV

      373




      373
























          1 Answer
          1






          active

          oldest

          votes


















          0














          In order to display HTML tags in React JSX, you need to pass the HTML string to dangerouslySetInnerHTML props. Not inside a JSX tag. Please check this official documentation about how to do it: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml



          So, instead doing this:



          <div className="my-custom-select">
          {allOptions}
          </div>


          You should doing this way:



          <div className="my-custom-select" dangerouslySetInnerHTML={{__html: allOptions}}/> 


          It is due to security concern. Quoted from React documentation:




          dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.




          If you insist to put the HTML string inside JSX tag instead passing to props, alternatively you can use an additional library from this NPM package: https://www.npmjs.com/package/react-html-parser . So, it will be something looks like this:



          import React from 'react';
          import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

          class HtmlComponent extends React.Component {
          render() {
          ........
          return <div className="my-custom-select">{ ReactHtmlParser(allOptions) }</div>;
          }
          }





          share|improve this answer


























          • This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

            – KingV
            Jan 1 at 9:30











          • I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

            – Bayu
            Jan 1 at 9:35











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53994160%2fusing-jsx-in-this-state-but-it-gets-rendered-as-plain-text%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          In order to display HTML tags in React JSX, you need to pass the HTML string to dangerouslySetInnerHTML props. Not inside a JSX tag. Please check this official documentation about how to do it: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml



          So, instead doing this:



          <div className="my-custom-select">
          {allOptions}
          </div>


          You should doing this way:



          <div className="my-custom-select" dangerouslySetInnerHTML={{__html: allOptions}}/> 


          It is due to security concern. Quoted from React documentation:




          dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.




          If you insist to put the HTML string inside JSX tag instead passing to props, alternatively you can use an additional library from this NPM package: https://www.npmjs.com/package/react-html-parser . So, it will be something looks like this:



          import React from 'react';
          import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

          class HtmlComponent extends React.Component {
          render() {
          ........
          return <div className="my-custom-select">{ ReactHtmlParser(allOptions) }</div>;
          }
          }





          share|improve this answer


























          • This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

            – KingV
            Jan 1 at 9:30











          • I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

            – Bayu
            Jan 1 at 9:35
















          0














          In order to display HTML tags in React JSX, you need to pass the HTML string to dangerouslySetInnerHTML props. Not inside a JSX tag. Please check this official documentation about how to do it: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml



          So, instead doing this:



          <div className="my-custom-select">
          {allOptions}
          </div>


          You should doing this way:



          <div className="my-custom-select" dangerouslySetInnerHTML={{__html: allOptions}}/> 


          It is due to security concern. Quoted from React documentation:




          dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.




          If you insist to put the HTML string inside JSX tag instead passing to props, alternatively you can use an additional library from this NPM package: https://www.npmjs.com/package/react-html-parser . So, it will be something looks like this:



          import React from 'react';
          import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

          class HtmlComponent extends React.Component {
          render() {
          ........
          return <div className="my-custom-select">{ ReactHtmlParser(allOptions) }</div>;
          }
          }





          share|improve this answer


























          • This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

            – KingV
            Jan 1 at 9:30











          • I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

            – Bayu
            Jan 1 at 9:35














          0












          0








          0







          In order to display HTML tags in React JSX, you need to pass the HTML string to dangerouslySetInnerHTML props. Not inside a JSX tag. Please check this official documentation about how to do it: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml



          So, instead doing this:



          <div className="my-custom-select">
          {allOptions}
          </div>


          You should doing this way:



          <div className="my-custom-select" dangerouslySetInnerHTML={{__html: allOptions}}/> 


          It is due to security concern. Quoted from React documentation:




          dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.




          If you insist to put the HTML string inside JSX tag instead passing to props, alternatively you can use an additional library from this NPM package: https://www.npmjs.com/package/react-html-parser . So, it will be something looks like this:



          import React from 'react';
          import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

          class HtmlComponent extends React.Component {
          render() {
          ........
          return <div className="my-custom-select">{ ReactHtmlParser(allOptions) }</div>;
          }
          }





          share|improve this answer















          In order to display HTML tags in React JSX, you need to pass the HTML string to dangerouslySetInnerHTML props. Not inside a JSX tag. Please check this official documentation about how to do it: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml



          So, instead doing this:



          <div className="my-custom-select">
          {allOptions}
          </div>


          You should doing this way:



          <div className="my-custom-select" dangerouslySetInnerHTML={{__html: allOptions}}/> 


          It is due to security concern. Quoted from React documentation:




          dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.




          If you insist to put the HTML string inside JSX tag instead passing to props, alternatively you can use an additional library from this NPM package: https://www.npmjs.com/package/react-html-parser . So, it will be something looks like this:



          import React from 'react';
          import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

          class HtmlComponent extends React.Component {
          render() {
          ........
          return <div className="my-custom-select">{ ReactHtmlParser(allOptions) }</div>;
          }
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 1 at 9:34

























          answered Jan 1 at 9:21









          BayuBayu

          538513




          538513













          • This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

            – KingV
            Jan 1 at 9:30











          • I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

            – Bayu
            Jan 1 at 9:35



















          • This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

            – KingV
            Jan 1 at 9:30











          • I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

            – Bayu
            Jan 1 at 9:35

















          This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

          – KingV
          Jan 1 at 9:30





          This got me on the right track. I had to put it in the above code though, not in the div.. allOptions.splice(index, 0, <b dangerouslySetInnerHTML={{__html: this.props.levelNames[j]}}/>); did the trick

          – KingV
          Jan 1 at 9:30













          I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

          – Bayu
          Jan 1 at 9:35





          I update the answer with another alternative way, if you may prefer to put HTML string inside JSX tag :)

          – Bayu
          Jan 1 at 9:35




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53994160%2fusing-jsx-in-this-state-but-it-gets-rendered-as-plain-text%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

          How to fix TextFormField cause rebuild widget in Flutter