Reputation: 564
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
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
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
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
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