React rendering variable with html characters escaped
React actually has a page that addresses this and some other potential solutions (using unicode characters, saving the file as utf8, using dangerouslySetInnerHtml): jsx-gotchas
Another option is to create a simple, reusable Temp component that has types you pass it:
const TEMP_C = 'C';
const TEMP_K = 'K';
const Temp = ({ children, unit }) => <span>{children}°{unit}</span>;
const App = () => (
<div>
<p>Temperature 1: <Temp unit={TEMP_K}>25</Temp></p>
<p>Temperature 2: <Temp unit={TEMP_C}>25</Temp></p>
</div>
);
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Judd Franklin
Make and maintain websites for companies and organizations with a special focus on nonprofits. We focus on making Wordpress sites that give users and admins mutually pleasurable user experiences. I personally really enjoy JavaScript development.
Updated on June 05, 2022Comments
-
Judd Franklin almost 2 years
I am learning React and have run into the following situation:
I have a string variable that I am passing as a prop to different components to be rendered by JSX.
When the component and its sub-components are rendered, the string does not render html special characters, instead rendering the character code as text.
How can I get the variable to render as html?
Here is the code for a component that works completely, except that the
tempUnitString
variable renders as° K
, while the<th>
below renders its units as ° K.import React, { Component } from 'react'; import { connect } from 'react-redux'; import Chart from '../components/chart'; import GoogleMap from '../components/google_map' class WeatherList extends Component { renderWeather(cityData, tempUnits){ const name = cityData.city.name; const id = cityData.city.id; const humidity = cityData.list.map(weather => weather.main.humidity); const pressure = cityData.list.map(weather => weather.main.pressure); const { lon, lat } = cityData.city.coord; let temp = cityData.list.map(weather => weather.main.temp); if (tempUnits === "K"){ temp = cityData.list.map(weather => weather.main.temp); } else if (tempUnits === "F"){ temp = cityData.list.map(weather => weather.main.temp * 9/5 - 459.67); } else { temp = cityData.list.map(weather => weather.main.temp - 273.15); } let tempUnitString = "° " + tempUnits; return ( <tr key={ id }> <td><GoogleMap lat={ lat } lon={ lon } /></td> <td> <Chart color="red" data={ temp } units={ tempUnitString } /> </td> <td> <Chart color="green" data={ pressure } units=" hPa" /> </td> <td> <Chart color="orange" data={ humidity } units="%" /> </td> </tr>); } render() { const tempUnits = this.props.preferences.length > 0 ? this.props.preferences[0].tempUnits : "K"; return ( <table className="table table-hover"> <thead> <tr> <th>City</th> <th>Temperature (° { tempUnits })</th> <th>Pressure (hPa)</th> <th>Humidity (%)</th> </tr> </thead> <tbody> { this.props.weather.map( item => this.renderWeather(item,tempUnits) ) } </tbody> </table> ); } } function mapStateToProps({ weather, preferences }){// { weather } is shorthand for passing state and { weather:state.weather } below return { weather, preferences }; // === { weather:weather } } export default connect(mapStateToProps)(WeatherList);
UPDATE
Using the documentation passed to me by @James Ganong I set up a boolean prop on the subcomponent
isTemp
and based on that created a JSX variable.The subcomponent (minus includes and func definitions) looks like this:
export default (props) => { let tempDeg = ''; if (props.isTemp){ tempDeg = <span>°</span>; } return ( <div> <Sparklines height={ 120 } width={ 100 } data={ props.data }> <SparklinesLine color={ props.color } /> <SparklinesReferenceLine type="avg" /> </Sparklines> <div>{ average(props.data)} { tempDeg }{ props.units }</div> </div> ); }
The call to it looks like this:
<Chart color="red" data={ temp } units={ tempUnits } isTemp={ true } />
-
Judd Franklin about 7 yearsHi Jordan, The problem is that I want to pass the concatenated string into a separate component as a param. I would rather not have to put clunky conditional logic into the subcomponent, or create separate components just to handle this one case.
-
Judd Franklin about 7 yearsI checked out your approach, and the problem appears to be with the way that the string is being passed to the subcomponent
-
Judd Franklin about 7 yearsPerhaps a conversion from string variable to props property changes rendering behavior?
-
Jordan Enev about 7 yearsHere is described what's happening: reactjs.cn/react/docs/jsx-gotchas.html. Thanks to James' answer.
-
Judd Franklin about 7 yearsThanks for this information. I marked it as the solution because you found documentation that I couldn't. haha. Ultimately, I need to customize this approach and use some conditional logic because I am running the temperature through a generic component that creates sparklines for temperature and other datasets. I'll add my final solution as an additional solution below.
-
Judd Franklin about 7 yearsI wound up just updating the question with the solution.
-
James Ganong about 7 yearsCheers - two things: 1. if you need to pass a prop as true (like
isTemp={true}
) you actually don't need the={true}
part, just by settingisTemp
as an attribute (without the equals) it evals to true. 2. You could combine the if statement into the jsx instead of needing to use thetempDeg
variable. ie replace{ tempDeg }
with{props.isTemp && (<span>°</span>)}
-
Judd Franklin about 7 yearsCheers to that as well!