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?
Tried using a template literal:
<MyPanel title={`${name} – ${description}`}> ... </MyPanel>
Problem: In the rendered output, the –
is being rendered literally as "–
" instead of as "–
".
Attempted to construct some simple JSX with no quotes:
<MyPanel title={{name} – {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} – {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:
+
-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.Coding JSXJSX allows us to write HTML elements in JavaScript and place them in the DOM without any createElement() and/or appendChild() methods.
To show HTML entities using React, we can wrap the HTML entity string with fragment. We wrap ³ in a fragment so that it'll be rendered.
Following approaches are there to access props inside quotes in React JSX: Approach 1: We can put any JS expression inside curly braces as the entire attribute value. Approach 2: We can use ES6 template literals.
Not only can JSX elements be passed as props to components, but we can also pass other components as props.
You can avoid the superfluous span
with a Fragment
:
<MyPanel title={<>{name} – {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 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} – ${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} – ${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>
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