Insert counter in a reactjs map - reactjs

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>

Related

Whats the best way to make use of a counter variable in this nested 'map' loop so that each square key or value incremenents up from 1 to 9

return (
<div>
<div className="board">
{
[1,2,3].map( (row) => {
return <div key={row} className="board-row">
{
[1,2,3].map( (col) => {
return <Square key={col}></Square>
})
}
</div>
})
}
</div>
</div>
);
How might i make it so the Squares generated by this nested for loop (using array map functions) could use a counter so that the square's value would be 0 to 8 or 1 to 9.
I am struggling to create a variable outside of these javascript arrow functions...
(I have a Java background and am struggling i little wrapping my head around javascript/react :) )
Many thanks for any help/direction.
John
EDIT:
Below is solution that worked for me in the end!
{
[1,2,3].map( (row) => {
return <div key={row} className="board-row">
{
[1,2,3].map( (col) => {
return this.renderSquare(++count);
})
}
</div>
})
}
</div>
Here is renderSquare function also:
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
key = {i}
/>
);
}
I think a lot of the confusion is because of JSX and learning how and when you can type HTML and/or JavaScript where.
FINAL EDIT:
please note, i changed from ++count to count++ to avoid the initial increment occurring too early. Doing this breaks the calculateWinner logic, just if anyone else is doing the tic tac toe tutorial! :)
If you just want to count and output the number of times the second loop is called then the following is a solution to it:
import React from 'react';
export default function Test2() {
let count = 0;
return (
<div>
<h1>Test 1 Component</h1>
{[1, 2, 3].map((row) => {
return (
<div key={row}>
{[1, 2, 3].map((col) => {
return <div key={col}>{++count}</div>;
})}
</div>
);
})}
</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>
);
})
}

How to render only the 3rd object from an array react

React newbie here. I have a component which gets an array of objects in JSON format and saves it into the state.
I am now unsure how I can render the name/description of only the 3rd object in the components render function.
I want to be able to only render the 1,2,3,4,5th object etc as well.
Any ideas?
https://codesandbox.io/s/admiring-ishizaka-rfp3k - Demo
return (
<div className="App">
{name1} // Object 1 name
{description1} // Object 1 description
{name2} // Object 2 name
{description2} // Object 2 description
</div>
);
To give you the basic idea, you can display the name of your 3rd component on your render like this:
render() {
return (
<div className="App">
{this.state.profiles.map((item, index) => {
return(
index === 2 ? item.name : ""
)
})}
</div>
);
}
Please use Array map
render() {
const { profiles } = this.state;
return (
<div className="App">
{
profiles.map(profile => (
{profile.name}
{profile.description}
))
}
</div>
);
}
render() {
return (
<div className="App">
{this.state.profiles.map((data, i) => {
return(
i=== 2 ? (<p>{data.name}</p>) :(<p> </p>)
)
})}
</div>
);
}

Mapping array to JSX elements inside rows

Using React I am trying to map an array of elements into a containing HTML element.
However I can not figure out how to map two elements into one HTML element since these elements will have to be closed.
This is an example of what I would like to do. Map two components inside a containing element of className="row" but I can not because the JSX elements have to be closed:
const CalendarGrid = (events) => {
let content = [];
events.events.map((event, index) =>{
if (index % 2 != 0) {
content.push(
<div className="row">
<EventCardRight key={event.id} event={event} align="right"/>
)
}if (index % 2 == 0)
{
content.push(
<EventCardLeft key={event.id} event={event} />
</div className="row">
);
}
});
return (
<div>
{content}
</div>
);
}
You can take advantage of inline logical operators and map through events directly as:
const CalendarGrid = (events) => {
return (
<div>
{events.events.map((event, index) =>
<div key={event.id} className="row">
{index % 2 != 0 ? (
<EventCardRight key={event.id} event={event} align="right"/>
) : (
<EventCardLeft key={event.id} event={event} />
)}
</div>
)}
</div>
)
}
First, I would split your array to chunks of size 2. See How to split a long array into smaller arrays, with JavaScript, I will use lodash for that:
const rows = _.chunk(events.events, 2);
now I can simply map every row to elements:
const content = rows.map((rowEvents, index) => (
<div key={index} className="row">
<EventCardRight event={rowEvents[0]} align="right" />
<EventCardLeft event={rowEvents[1]} />
</div>
));

Reactjs have <div> wrapper the elements on every 4th elements

React group 4 items in a div with class row. At the moment you can see below I have a <div> group around the articles.
// articles is array of article object
<div className="row">
<section className="section--6-or-4-items section-featured campaign-teasers">
{articles.map(item => <Teaser {...item} key={item.id} />)}
</section>
</div>
Should I create a new component which have <div> wrapper around and only accept 4 arrays at a time to render out the articles.
Your best bet here is to build your array of articles into an array of 4-length arrays. You can do this using lodash's handy chunk method.
Once you've chunked your articles, you can iterate over them in your JSX, something like this:
const sections = chunk(articles, 4);
return (
<div className="row">
{sections.map((articles, i) => (
<section className="..." key={i}>
{articles.map(item => <Teaser {...item} key={item.id} />)}
</section>
)}
</div>
);
Edit: If you don't want to use lodash, you can use reduce to great effect:
function chunk(array, size) {
return array.reduce((chunks, item, i) => {
if (i % size === 0) {
chunks.push([item]);
} else {
chunks[chunks.length - 1].push(item);
}
return chunks;
}, []);
}
Personally, I extract rendering to dedicated methods.
<div className="row">
<section className="section--6-or-4-items section-featured campaign-teasers">
{ this.renderArticles() }
</section>
</div>
Renderer method here...
renderArticles() {
return createChunks(articles, 4).map((chunk, idx) => (
<div key={idx}>
{ chunk.map((props, idx) => <Teaser key={idx} {...props} />) }
</div>
));
},
And finally, function which chunks array into smaller array on N size
const createChunks = (array, size) => {
const copy = array.concat();
const chunks = [];
while (copy.length) {
chunks.push( copy.splice(0, size) );
}
return chunks;
}

Resources