React is rendering [object object], not JSX

I am trying to display log entries on my site using an object (not an array) and I am facing a problem, 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 div is normal text.

When I change the loop to say " journalEntries = <div....

", it outputs the last log entry as expected, but the problem is that it doesn't actually add log entries to the loop.

ideas?

+3


source to share


4 answers


Inserting the definition journalEntries

as a string defines it as an array and pushes the JSX elements onto the array to do as

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 add to String, you are not actually adding the string, but an object, which is wrong, and hence you get [Object Object]



You can also use a map to display your context. See this answer on how to use the map:

REACT JS: displaying data and manipulating arrays

+4


source


Why don't you use .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>
    );
}

      

+3


source


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>
    );
}

      

+2


source


you already have state log data, why are you building the element outside of the render? the correct way to do this is to map it directly to the 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>);
}

      

don't forget to put a "key" on each displayed item.

+1


source







All Articles