1

I'm rendering some paragraphs using React. Inside those paragraphs there should be a span for footnotes. The best I got so far is that it rendered [object Object].

function ArticleItem() {
  const articles = [
    {
      title: "title",
      content: [
        `Text based on this footnote <span>1</span>`,
        `Another argument, here is my source <span>2</span>`
      ]
    }
  ];

  return (
    <div className="article-container">
      <h3> {articles[i].title} </h3>
       {
        articles[i].content.map(paragraph => (
        <p>
         { paragraph }
        </p>
        )
       }    
    </div>
  );
}
Moshe M
  • 91
  • 1
  • 1
  • 8
  • Maybe [this](https://stackoverflow.com/a/39758914/5955493) answer your question – Erick ls Jan 04 '20 at 19:35
  • Hi Moshe. I saw that you have a very low ratio of questions/accepted answers, but you are commenting on the answers "thank you, it works" and things like that. The proper way to accept an answer is by clicking the green check on the left of the answer. This is mandatory to have StackOverflow clean – Jorge Fuentes González Mar 20 '20 at 17:37
  • Ok, I will use it next time. – Moshe M Mar 22 '20 at 13:18

2 Answers2

1

Because you are creating a string with "<span>" instead of creating actual <span> HTML elements. What you are using is named jsx, which converts HTML tags to their corresponding document.createElement() (or similar, which in React has it own way).

If you want the content to be an HTML element and not a string, then create an HTML element:

function ArticleItem() {
  const articles = [
    {
      title: "title",
      content: [
        <p>Text based on this footnote <span>1</span></p>,
        <p>Another argument, here is my source <span>2</span></p>
      ]
    }
  ];

  return (
    <div className="article-container">
      <h3> {articles[i].title} </h3>

      { articles[i].content.map(paragraph => paragraph) }
    </div>
  );
}

Notice how I removed the string literal (``) and created an HTML element.

If the article content comes from an API call, then avoid using HTML tags inside strings. That's a bad practice actually. Always create the tags within the render() call and populate them with the API data you received.

Jorge Fuentes González
  • 11,568
  • 4
  • 44
  • 64
  • Interesting approach. I was creating an array of strings. But it didn't strike me to directly maintain

    . Does the job

    – rahulxyz Nov 06 '21 at 15:24
1

Assuming the content array has to be supplied as raw HTML, a common solution is to use the dangerouslySetInnerHTML prop to render that HTML directly. You can introduce that to your <p> elements like this:

articles[i].content.map(paragraph => (
    <p dangerouslySetInnerHTML={{ __html: paragraph }} />
))

A few other things to consider; I noticed a missing ) in your code after the <p> element of your map statement which will be causing a syntax error. Also, ensure that i is defined to an index in range of your articles array. Here's an example of each fix applied:

function ArticleItem() {
  const articles = [
    {
      title: "title",
      content: [
        `Text based on this footnote <span>1</span>`,
        `Another argument, here is my source <span>2</span>`
      ]
    }
  ];

  const i = 0;

  return (
    <div className="article-container">
      <h3> {articles[i].title} </h3>
       {
        articles[i].content.map(paragraph => 
        (<p dangerouslySetInnerHTML={{ __html: paragraph }} />)
        )
       }    
    </div>
  );
}

Here's a working example as well - hope that helps!

Dacre Denny
  • 29,664
  • 5
  • 45
  • 65