Keywords: React Components | HTML Rendering | XSS Protection
Abstract: This technical article provides an in-depth examination of three primary methods for passing and rendering HTML tags in React components: utilizing JSX element arrays for type-safe rendering, employing dangerouslySetInnerHTML for raw HTML string processing, and leveraging props.children for component content transmission. The paper thoroughly analyzes the implementation principles, applicable scenarios, and security considerations for each approach, with particular emphasis on XSS attack risks and corresponding preventive measures. Through comparative analysis of different solutions' advantages and limitations, it offers comprehensive technical guidance and best practice recommendations for developers.
Technical Challenges in HTML Tag Transmission in React
In React development practice, developers frequently encounter the need to pass text content containing HTML tags to components. As illustrated in the user's question, when attempting to pass <MyComponent text="This is <strong>not</strong> working." />, directly outputting this.props.text within the component yields the raw string This is <strong>not</strong> working. rather than the expected bold text effect. This phenomenon stems from React's default security mechanism—all strings passed through props are automatically escaped to prevent cross-site scripting attacks.
JSX Element Array Solution
React's officially recommended primary solution involves using JSX element arrays. This method achieves safe and controllable HTML rendering by splitting text content into mixed arrays of strings and JSX elements:
// Component usage example
<MyComponent text={["This is ", <strong>not</strong>, " working."]} />
// Component internal implementation
class MyComponent extends React.Component {
render() {
return (
<div>
{this.props.text}
<div>
);
}
}The advantage of this approach lies in its complete adherence to React's design philosophy, where all JSX elements are processed through React's virtual DOM, ensuring type safety and rendering performance. Each element in the array can be a string, JSX tag, or React component, providing significant flexibility. It's important to note that when rendering arrays, React requires unique key attributes for each child element to avoid performance issues.
Cautious Use of dangerouslySetInnerHTML
For scenarios requiring raw HTML string processing, React provides the dangerouslySetInnerHTML property. This method directly inserts HTML strings into the DOM, bypassing React's escaping mechanism:
class MyComponent extends React.Component {
render() {
return (
<div
dangerouslySetInnerHTML={{ __html: this.props.htmlContent }}
/>
);
}
}
// Usage example
<MyComponent htmlContent="This is <strong>not<strong> working." />While this method resolves HTML rendering issues, it carries significant security risks. As the property name indicates, this is a "dangerous" operation because it may introduce XSS attack vulnerabilities. Attackers could inject malicious scripts to execute unauthorized operations. Therefore, before using this method, it's essential to ensure that HTML content originates from trusted sources or undergoes rigorous content sanitization.
Content Transmission via props.children
React also supports passing component content through props.children, a pattern particularly suitable for wrapper components or layout components:
// Component definition
function Card({ children }) {
return (
<div className="card">
{children}
<div>
);
}
// Usage example
<Card>
<h3>Title Content<h3>
<p>This is a paragraph containing <strong>bold text<strong><p>
<Card>The advantage of this pattern is its semantic clarity and alignment with React's component composition philosophy. It allows direct use of JSX syntax in parent components, avoiding the complexity of string parsing. However, this method primarily suits static content or fully controllable dynamic content, with limited support for scenarios requiring dynamic HTML generation from external data sources.
Security Considerations and Best Practices
When handling HTML content rendering, security should always be the primary consideration. Based on discussion of Q&A data and reference articles, the following security practices can be summarized:
First, prioritize the JSX element array solution as the safest approach. It remains entirely within React's control scope without introducing additional security risks.
Second, if dangerouslySetInnerHTML must be used, implement strict content validation and sanitization. Specialized libraries like DOMPurify can be employed to clean HTML content, removing potential malicious scripts.
The triple handlebars syntax {{{title}}} mentioned in reference articles for template engine usage also reflects similar security considerations—unescaped HTML output requires careful handling. This reminds us that directly outputting unverified HTML poses security risks in any frontend framework.
Performance and Maintainability Comparison
From a performance perspective, the JSX element array solution typically offers optimal rendering performance by fully leveraging React's virtual DOM diffing algorithm. In contrast, dangerouslySetInnerHTML bypasses the virtual DOM and directly manipulates the real DOM, potentially affecting performance during extensive dynamic updates.
Regarding maintainability, JSX element arrays provide the best development experience, supporting complete TypeScript type checking and IDE intelligent suggestions. Comparatively, string-form HTML content is difficult to statically analyze, increasing maintenance costs.
Considering all factors, development teams are advised to establish clear content rendering standards: use JSX element arrays for internally controllable content, and implement rigorous security review and sanitization for HTML content that must be received from external sources.