ELI7VH
ELI7VH

Reputation: 564

React is rendering [object object] rather than the JSX

I'm trying to render out journal entries on my site with an object (not array) and I am running into an issue, here is my current code

  populateJournal(){
const j = Object.values(this.state.journal);
var journalEntries = '';

  for (var i = 0; i < j.length; i++){
    journalEntries+=
      <div>
      <h3>{j[i].title} - {j[i].date}</h3>
      <p>{j[i].entry}</p>
      </div>;

  }

 return(<div>{journalEntries}</div>);

}

When i call this function it renders "<div>[object object]</div>" and the text between the divs is plain text.

When i change the loop to say "journalEntries = <div...." it renders out the last journal entry as expected, but the issue is that it's not actually appending the journal entries with the loop.

ideas?

Upvotes: 41

Views: 80870

Answers (4)

Shubham Khatri
Shubham Khatri

Reputation: 281636

Instead of a defining journalEntries as a string define it as an array and push the JSX elements to the array in order to render, for example:

populateJournal() {
  const j = Object.values(this.state.journal);
  var journalEntries = [];
  for (var i = 0; i < j.length; i++) {
    journalEntries.push(
      <div>
        <h3>{j[i].title} - {j[i].date}</h3>
        <p>{j[i].entry}</p>
      </div>
    );
  }
     
  return (<div>{journalEntries}</div>);
}

When you append to the string, you are not actually appending a string but an object which is incorrect and hence you get [object Object]

You can also use map to render your context. See this answer on how to use map:

REACT JS: Map over an array of objects to render in JSX

Upvotes: 39

Grand Julivan
Grand Julivan

Reputation: 279

you already have the journal data on state, why would you construct the element outside render? the correct way to do it is to map it directly on render.

 populateJournal(){
     const j = Object.values(this.state.journal);
     return(<div>{
       j && j.map((journal,i)=>{
       return  (  <div key={"journal"+i}>
          <h3>{journal.title} - {journal.date}</h3>
          <p>{journal.entry}</p>
          </div>
       })
      }</div>);
}

remember to put the "key" on each mapped element.

Upvotes: 1

user5738822
user5738822

Reputation:

Why you don't use from .map(), try this:

render(){ 
    const j = Object.values(this.state.journal);
    return(
        <div>
           {j.map((item,index) => 
               <div key={index}>
                  <h3>{item.title} - {item.date}</h3>
                  <p>{item.entry}</p>
               </div>
           )}
        </div>
    );
}

Upvotes: 7

bier hier
bier hier

Reputation: 22520

You don't need popluateJournal, just use this in render():

 render() {
    //const j = Object.values(this.state.journal);
    const j = [{'title':'one','date':'12/03/17','entry':'This is an entry'},
            {'title':'two','date':'14/03/17','entry':'This is another entry'}
        ];

    //inject j as property into Test
    const Test = ({journals}) => (
            <div>
                {journals.map(journal => (
                    <div>
                        <h3>{journal.title} - {journal.date}</h3>
                        <p>{journal.entry}</p>
                    </div>
                ))}
            </div>
        );

    return (
            <div><Test journals={j}></Test></div>
    );
}

Upvotes: 3

Related Questions