How to loop an array inside an array with React - arrays

Hello I have some data I am trying to display with react that looks like this
snapshot
there is an Options array inside of the Poll array.
How do I display the options array with react when I am already mapping the Poll array? This is what i have so far:
renderPost(posts){
return posts.map((post) => {
return (
<div>
<h3>{post.question}</h3>
</div>
);
});
}

Something like
renderPost(posts){
return posts.map(post =>
<div>
<h3>{post.question}</h3>
<ul>
{post.options.map(option =>
<li>{option.title}</li>
)}
</ul>
</div>
)
}

You should never forget add a key to the jsx element when generate them in loop. The key should be unique and key should be from data, if your data doesn't contain unique id per object then use index as a key like below
Unique id as key from data
return posts.map(post =>
<div key={post.id}>
<h3>{post.question}</h3>
<ul>
{post.options.map(option =>
<li key={option.id}>{option.title}</li>
)}
</ul>
</div>
)
Use index as a key if you don't have unique id in data array
return posts.map((post, index) =>
<div key={`Key${index}`}>
<h3>{post.question}</h3>
<ul>
{post.options.map((option, i) =>
<li key={`Key${i}`}>{option.title}</li>
)}
</ul>
</div>
)

Related

Insert counter in a reactjs map

I'm starting to ReactJs and have a doubt when generating a list with an ordering. How do I include a counter inside my map?
The way I'm doing it is repeating the number 1 in all records. I wanted each record to have a counter (1 Adam, 2 Andrew, 3 Sophia ...)
<div>
{
data.contacts.data.map((contact) => {
return (
<div>
<span>1</span> <b>{contact.data.name} {contact.data.email}</b>
</div>
)
})
}
</div>
Use the second argument (array index) of the map method:
<div>
{
data.contacts.data.map((contact, index) => (
<div>
<span>{index + 1}</span> <b>{contact.data.name} {contact.data.email}</b>
</div>
))
}
</div>
With map you have access to the index. So you can use the index to add a counter. Also, remember to add a key-value to each child you're printing with map (you can use the index for this).
<div>
{
data.contacts.data.map((contact, index) => {
return (
<div key={index}>
<span>{index + 1}</span> <b>{contact.data.name} {contact.data.email}</b>
</div>
)
})
}
</div>

Why doesn't `index` qualify as a unique key, when passed as part of props to a custom react component?

When I just list the items directly, using index works. As in the following.
<ol className="item-list">
{
props.items.map((item, index) => (
<li key={index}>{item}</li>
))
}
</ol>
But when I create a custom component to represent the list item, using index doesn't seem to qualify as being unique... And I end up getting a warning, as in the following.
<ol className="item-list">
{
props.items.map((item, index) => (
<ShoppingItem
index={index}
item={item}
/>
))
}
</ol>
The ShoppingItem is a simple component, like the following.
const ShoppingItem = props => (
<li key={props.index}>{props.item}</li>
);
And the warning I get in the console is the following.
Warning: Each child in a list should have a unique "key" prop.
You should read carefully the react docs for Lists and Keys: Extracting components with keys. The key goes on the component being mapped, not what it renders.
Incorrect
const ShoppingItem = props => (
<li key={props.index}>{props.item}</li>
);
<ol className="item-list">
{
props.items.map((item, index) => (
<ShoppingItem
index={index}
item={item}
/>
))
}
</ol>
Correct
<ol className="item-list">
{
props.items.map((item, index) => (
<ShoppingItem
key={index} // <-- key goes here
item={item}
/>
))
}
</ol>

Map and Sort Methods for component in React?

Relatively new to React and trying to sort the mapped prop nearbyRestaurants alphabetically by place.name. Is there a way I can chain the sort method to the end of the map method to alphabetize the list?
export default function RestaurantList({nearbyRestaurants}) {
return (
<div>
<ul>
<li className="list-header">Restaurants</li>
{nearbyRestaurants.map((place) => (
<div>
<li>
<div>{place.name}</div>
<div>{place.vicinity}</div>
</li>
</div>
))}
</ul>
</div>
);
}
Sort the array before mapping it.
function sortAlphabetically(a,b){
return a.name.localeCompare(b.name)
}
export default function RestaurantList({nearbyRestaurants}) {
return (
<div>
<ul>
<li className="list-header">Restaurants</li>
{nearbyRestaurants.sort(sortAlphabetically).map((place) => (
<div>
<li>
<div>{place.name}</div>
<div>{place.vicinity}</div>
</li>
</div>
))}
</ul>
</div>
);
}

Map an array inside an object inside an array React JS

I have an Array of Objects, and those objects have an object with an array in it. I want to map the "shoot: Array(6)" so I can list out the items.
How would I go about this? Im able to map the name, id, and instructions, but im having trouble getting access to and mapping the shots object then shoot array.
Current Code Information:
{Object.values(instructions).map(({id, name, Instructions}, i) => {
return (
<div key={id}>
<p><b>{name}</b></p>
<p>{Instructions}</p>
</div>
);
})}
You can map on the shoots array within each object like this:
{Object.values(instructions).map(({id, name, Instructions}, i) => {
return (
<div key={id}>
<p><b>{name}</b></p>
<p>{Instructions}</p>
{shoot.shoots.map(shoot => (<p>{shoot}</p>))}
</div>
);
})}
try this code:
{Object.values(instructions).map(({id, name, instructions, shots}, i) => {
return (
<div key={id}>
<p><b>{name}</b></p>
<p>{instructions}</p>
<p>{shots.amount}</p>
{shots.shoot.map(item => (
<div>{item}</div>
))}
</div>
);
})}
Destruct the Shots object along with {id, name, Instructions} and map the shoots array from the Shots object.
{
Object.values(instructions).map(({id, name, Instructions, Shots}, i) => {
return (
<div key={id}>
<p><b>{name}</b></p>
<p>{Instructions}</p>
{
Shots.shoots.map(shoot => (<p>{shoot}</p>))
}
</div>
);
})
}

Why am I getting a warning of not having a unique key?

This is my render
render() {
let products = this.state.products
return (
<ul>
{products.map((product, index) => Product({ key: index, product: product }))}
</ul>
);
}
I am using a unique key, and still get the warning
Warning: Each child in an array or iterator should have a unique "key"
prop.
That's not how you return a Component or pass it the key prop (or any other props...)
<ul>
{products.map((product, index) => (
<Product key={index} product={product} />
))}
</ul>
https://reactjs.org/docs/components-and-props.html#composing-components
I found this for you.
How to create unique keys for React elements?
It seems like you need to have a return for the key.
Or, as it states, npm packages already exist to declare unique keys.
You are not passing child elements to the ul
render() {
let products = this.state.products
return (
<ul>
{products.map((product, index) =>
<li key={index}>
{product}
</li>}
</ul>
);
}
I'm seeing this:
function Product(props) {
return (
<p key={props.key}>{props.product}</p>
)
}
function Main(props) {
let products = [ "foo", "bar", "baz"];
return (
<ul>
{products.map((product, index) => Product({key: index, product: product }))}
</ul>
);
}
ReactDOM.render(
<Main></Main>,
document.getElementById('example')
);
and this:
function Product(props) {
return (
<p>{props.product}</p>
)
}
function Main(props) {
let products = [ "foo", "bar", "baz"];
return (
<ul>
{products.map((product, index) => (
<li key={index}>
{Product({product: product })}
</li>
))}
</ul>
);
}
ReactDOM.render(
<Main></Main>,
document.getElementById('example')
);
Do what you're trying to accomplish.
If I had to guess (I don't have high confidence in this explanation), I would suspect that React requires a key prop on child components to so that it can quickly determine which elements need to be re-rendered when state changes. Therefore, passing a key prop won't actually achieve anything unless it's actually rendered as UI. The two examples above are rendering keys to the virtual DOM in the <p> and <li> respectively.

Resources