Reputation: 187
I want to simply output a list of <p>
tags but do no know the correct syntax.
I verified the data is correctly stored in this.props.bookmarks.bookmarks
but could not figure out how to render it correctly.
I verified that there is a bookmark.title
property as well.
With in the React component render()
function I have as follow:
return (
// ... snip
this.props.bookmarks.bookmarks.map((bookmark) => {
return "<p>{bookmark.title}</p>";
});
// ... snipt
)
Update:
var titles = this.props.bookmarks.bookmarks.map((bookmark) => {
return <div className='bookmark_div' id='generated1'>
<img className='bookmark_image' id='generated2' src='http://arcmarks.com/_images/sv_favicon.svg'/>
<a className='bookmark_link' id='generated3'>arcmarks</a>
</div>
});
Upvotes: 0
Views: 86
Reputation: 17132
If you are outputting an iterable in this manner, React is going to throw a warning/error about keys, so you should attach a unique identifier also. React uses these keys to help optimize rendering as it monitors updates to the DOM.
It looks like this is embedded inside other JSX code also, so you may need to wrap it in {}
return (
// ... snip
{this.props.bookmarks.bookmarks.map((bookmark) => {
return <p key={bookmark.id}>{bookmark.title}</p>;
});}
// ... snip
)
You could also optimize this further by destructuring the bookmarks iterable out, and utilize implicit return:
const { bookmarks } = this.props.bookmarks
return (
// ... snip
{bookmarks.map((bookmark) => <p key={bookmark.id}>{bookmark.title}</p>)}
// ... snip
)
In my example, bookmark.id
could be anything as long as it's unique, even bookmark.title
.
To come full circle, I will just add an example that shows this inside some additional JSX/HTML so you can see it:
constructor(props) {
super(props)
// set initial button state to false
this.state = {
buttonClicked: false
}
}
// method to handle button clicking
handleButton(e) {
e.preventDefault()
console.log('Radical button firing.')
// set state to opposite of current
this.setState({ buttonClicked: !this.state.buttonClicked })
}
render() {
if (!this.props.bookmarks) return <div>Loading...</div>
const { bookmarks } = this.props.bookmarks
return (
<div>
<h3>Checkout my Rad Books</h3>
{bookmarks.map((bookmark) => <p key={bookmark.id}>{bookmark.title}</p>)}
<button onClick={(e) => this.handleButton(e)}>{(!this.state.buttonClicked) ? 'Not Clicked Yet' : 'Was Clicked'}</button>
</div>
)
}
When you render, you must always wrap in a parent element, in this case, we used a div. I included some wealthy data here so you can forensically analyze and test further.
We might aswell go all out here. We can pull that book list into a rendering method also:
renderBooks() {
if (!this.props.bookmarks.bookmarks) return <div>Loading bookmarks...</div>
const { bookmarks } = this.props.bookmarks
return (
<div>
{bookmarks.map((bookmark) => <p key={bookmark.id}>{bookmark.title}</p>)}
</div>
)
}
render() {
return (
<div>
<h3>Checkout my Rad Books</h3>
{this.renderBooks()}
<button onClick={(e) => this.handleButton(e)}>{(!this.state.buttonClicked) ? 'Not Clicked Yet' : 'Was Clicked'}</button>
</div>
)
}
Upvotes: 3
Reputation: 146
return "<p>{bookmark.title}</p>";
You seem to be trying to interpolate. You shouldn't need to interpolate it.
return <p>{bookmark.title}</p> should be good.
If you're using ES6, you can interpolate using backticks.
`My name is ${name}`
Upvotes: 0
Reputation: 9157
Assuming you have setup Babel (or some other transpiler) correctly:
return <p>{bookmark.title}</p>;
should work (no "
s).
This will compile to:
React.createElement('p', null, bookmark.title);
(or something similar) in the resulting JS output.
If you want to render multiple lines of HTML, wrap your JSX in ()
s:
return (
<div>
<p>content here</p>
</div>
)
Upvotes: 1