1

New to ReactJS. I'm mapping over an array of data, some of which are strings with HTML tags. I'm trying to figure out how to render the html so that it's functional HTML. Currently it's outputted as a string in the browser.

Data:

const PROJECTS = [
  {
    id: 1,
    title: 'Website',
    dates: 'December 2015 - December 2017',
    description: 'Did some freelance work for <a href="www.website.com">website.com</a>.',
  },
  {
    id: 2,
    title: 'Website',
    dates: 'December 2015 - December 2017',
    description: 'Did some freelance work for <a href="www.website.com">website.com</a>.',
  }
];

export default PROJECTS;

React Component

import React, { Component } from 'react';
import PROJECTS from '../data/projects';

class Projects extends Component {
  render() {
    return (
      
          <div>
            {PROJECTS.map(PROJECT => {
              return(
                <article key={PROJECT.id}>
                  <h2>{PROJECT.title}</h2>
                  <p>{PROJECT.dates}</p>
                  <p>{PROJECT.description}</p>
                </article>
              )
            })}
          </div>

    )
  }
}

export default Projects;

1

4 Answers 4

2

Change your Projects so that the HTML is composed of JSX instead:

import React from 'react';
const PROJECTS = [
  {
    id: 1,
    title: 'Website',
    dates: 'December 2015 - December 2017',
    description: <>Did some freelance work for <a href="www.website.com">website.com</a>.</>,
  },
  {
    id: 2,
    title: 'Website',
    dates: 'December 2015 - December 2017',
    description: <>Did some freelance work for <a href="www.website.com">website.com</a>.</>,
  }
];

Them, <p>{PROJECT.description}</p> - which you already have - will render the JSX.

(You do need to import React, even though you're not creating a component - since this requires JSX, and JSX requires React.createElement, a React import is required)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick help. These were all great answers, however I chose yours as I have control over this particular data file.
2

There is a prop for visible html tag: dangerouslySetInnerHTML

Example:

const PROJECTS = [
    {
        id: 1,
        title: 'Website',
        dates: 'December 2015 - December 2017',
        description: 'Did some freelance work for <a href="www.website.com">website.com</a>.'
    },
    {
        id: 2,
        title: 'Website',
        dates: 'December 20' +
            '15 - December 2017',
        description: 'Did some freelance work for <a href="www.website.com">website.com</a>.'
    }
];


class Projects extends Component {
    render() {
        return (

            <div>
                {PROJECTS.map(PROJECT => {
                    return(
                        <article key={PROJECT.id}>
                            <h2>{PROJECT.title}</h2>
                            <p>{PROJECT.dates}</p>
                            <p dangerouslySetInnerHTML={{ __html:PROJECT.description}}></p>
                        </article>
                    )
                })}
            </div>

        )
    }
}

1 Comment

Thank you for showing me how to use dangerouslySetInnerHTML. I've read about this before, but I often stumble over the correct implementation.
2

An option is using the react-html-parser library https://www.npmjs.com/package/react-html-parser which will avoid dangerouslySetInnerHTML. It also means you wouldn't need to manipulate your array if it was coming directly from an API, for example (but it's always good practice to sanitize it anyways).

The updated code would look like:

import React, { Component } from 'react';
import PROJECTS from '../data/projects';
import ReactHtmlParser from 'react-html-parser';

class Projects extends Component {
  render() {
    return (
      
          <div>
            {PROJECTS.map(PROJECT => {
              return(
                <article key={PROJECT.id}>
                  <h2>{PROJECT.title}</h2>
                  <p>{PROJECT.dates}</p>
                  <p>{ReactHtmlParser(PROJECT.description)}</p>
                </article>
              )
            })}
          </div>

    )
  }
}

export default Projects;

Comments

1
Without using any third party library use `dangerouslySetInnerHTML` but you have to be sure you get valid html in the response everytime

return (
    <div>
        {PROJECTS.map(PROJECT => {
            return (
                <article key={PROJECT.id}>
                    <h2>{PROJECT.title}</h2>
                    <p>{PROJECT.dates}</p>
                    <p dangerouslySetInnerHTML={{ __html: PROJECT.description }}></p>
                </article>
            )
        })}
    </div>
)

1 Comment

Thank you for showing me how to use dangerouslySetInnerHTML. I've read about this before, but I often stumble over the correct implementation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.