React props: Using an HTML entity within JSX dynamic content?

I have a React component, to whose props I want to assign a string that includes both JavaScript variables and HTML entities.

Some of the approaches I've attempted have resulted in the HTML entity being rendered escaped. For example, – gets rendered literally as " – " instead of as " ".

Is there a way to get an HTML entity to render unescaped in a JSX dynamic content block being assigned to a React props?

Attempts Made

Tried using a template literal:

<MyPanel title={`${name} &ndash; ${description}`}> ... </MyPanel>

Problem: In the rendered output, the &ndash; is being rendered literally as " &ndash; " instead of as " ".


Attempted to construct some simple JSX with no quotes:

<MyPanel title={{name} &ndash; {description}} ... </MyPanel>

Problem: This failed at compile time with a syntax error.


Tried working around the syntax error by wrapping the JSX in a <span /> element:

<MyPanel title={<span>{name} &ndash; {description}</span>} ... </MyPanel>

Problem: This works, but I'd rather avoid the superfluous <span /> element being present in the rendered output.


Tried replacing the HTML entity with a Unicode numeric character reference:

<MyPanel title={name + ' u2013 ' + description} ... </MyPanel>

Problems:

  • This works, but (in my opinion) makes the code a little less readable. (It's more obvious that "ndash" rather than "2013" represents an en-dash character.)
  • Also, this involves + -operator concatenation, which triggers a Unexpected string concatenation prefer-template error in my team's JSLint checker; a solution that uses string interpolation instead would be better.

  • You can avoid the superfluous span with a Fragment :

    <MyPanel title={<>{name} &ndash; {description}</>} ... </MyPanel>
    

    This feature was introduced in React 16.2.

    See the Documentation


    I agree with @samanime that using the actual character is best for simple cases, but if your content is truly dynamic, I would prefer using a Fragment over either the entityToChar or dangerouslySetInnerHTML approaches.


    Here is React's documentation on HTML entities: JSX Gotchas

    Of those, using the actual character instead of the HTML entity would be the best:

    <MyPanel title={ `${name} – ${description}` } />
    

    If you can't do that because the HTML entity is dynamic (it's not just a hard-coded en-dash), you could translate the entity. Here is a little function that can do that:

    const entityToChar = str => { 
      const textarea = document.createElement('textarea'); 
      textarea.innerHTML = str; 
      return textarea.value; 
    }
    

    You then use it like this:

    <MyPanel title={ entityToChar(`${name} &ndash; ${description}`) } />
    

    Here are a few options (I outlined these in a more general answer awhile back):

  • Easiest - Use Unicode

    <MyPanel title={ `${name} – ${description}` } />
    
  • Safer - Use the Unicode number for the entity inside a Javascript string.

    <MyPanel title={`${name} u2013 ${description}`} />
    

    or

    <MyPanel title={`${name} ${String.fromCharCode(8211)} ${description}`} />
    
  • Last Resort - Insert raw HTML using dangerouslySetInnerHTML.

    title={`${name} &ndash; ${description}`}
    

    with:

    <div dangerouslySetInnerHTML={{__html: props.title}}></div>
    
  • const MyPanel = (props) => {
      return (
        <div>{props.title}</div>
      )
    }
    
    const MyPanelwithDangerousHTML = (props) => {
      return (
        <div dangerouslySetInnerHTML={{__html: props.title}}></div>
      )
    }
    
    var description = "description";
    var name = "name";
    
    ReactDOM.render(<MyPanel title={`${name} – ${description}`} />
    , document.getElementById("option1"));
    
    ReactDOM.render(<MyPanel title={`${name} u2013 ${description}`} />
    , document.getElementById("option2"));
    
    ReactDOM.render(<MyPanel title={`${name} ${String.fromCharCode(8211)} ${description}`} />
    , document.getElementById("option3"));
    
    ReactDOM.render(<MyPanelwithDangerousHTML title={`${name} &ndash; ${description}`} />
    , document.getElementById("option4"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
    
    <div id="option1"></div>
    <div id="option2"></div>
    <div id="option3"></div>
    <div id="option4"></div>
    链接地址: http://www.djcxy.com/p/52098.html

    上一篇: grunt browserify反应需要jquery

    下一篇: React道具:在JSX动态内容中使用HTML实体?