React map function not assinging keys properly - javascript

for some reason, I get the "each child in a list should have unique key" error when returning the following code. I do not understand why this happens, as I specifically assign the key during mapping:
return (
<>
{sortfeedCards(feedCards)}
{loggedIn === true ? (feedCardsMod.map((card, index) => (
<>
<p>{index}</p>
<FeedCard key={index} cardData={card} loggedIn={loggedIn} />
</>
))) : ('')}
</>
)
And here's what the render looks like.. it seems to me that the index-variable does work:
Many Thanks in advance!

The key needs to be on the outermost element, so on the Fragment, not the FeedCard:
feedCardsMod.map((card, index) => (
<React.Fragment key={index}>
<p>{index}</p>
<FeedCard cardData={card} loggedIn={loggedIn} />
<React.Fragment/>
))
(The shorthand syntax <></> for fragments doesn't allow keys, so i switched to using React.Fragment explicitly)

Try this:
return (
<>
{sortfeedCards(feedCards)}
{loggedIn === true ? (feedCardsMod.map((card, index) => (
<div key={index}>
<p>{index}</p>
<FeedCard cardData={card} loggedIn={loggedIn} />
</div>
))) : ('')}
</>
)
Keys must be unique amongst the enclosing tags:
https://reactjs.org/docs/lists-and-keys.html

Related

Rendering Multiple jsx with map and contains throws syntax error : ReactJS

I am trying to render jsx using map and then using includes to display a text based on the value present in the list. It throws error saying "message": "Unexpected token. Did you mean {'}'}or}`. Can someone help me with this
The code that I have tried:
return (
<>
{list.length
?
list.map((item, idx) => {
return (
<span key={idx}>
{item}
</span>
)}
{list.includes("Test") && (
<span key="test">
Replacement
</span> )
}
)
: "-"}
</>
);
You are calling list.includes inside your map function after you closed the curly bracket. I think you wanted something like this:
return (
<>
{list.length
?
(<>
{list.map((item, idx) => {
return (
<span key={idx}>
{item}
</span>
)}
)}
{list.includes("Test") && (
<span key="test">
Replacement
</span> )
}
</>)
: "-"}
</>
);

Get current index of an item with Object.entries().map

I know it is probably a silly question but I can' find an answer by myself, so..
How can I get current index with this construction .map(([key, value])?
to access it inside the map function bellow
return (
<Fragment>
{Object.entries(props.values).map(([key, value]) => {
return (
<Button
key={key}
value={value}
/>
);
})}
</Fragment>
);
You can obtain an index from callback in map
return (
<Fragment>
{Object.entries(props.values).map(([key, value], index) => {
return (
<Button
key={key}
value={value}
/>
);
})}
</Fragment>
);
Please check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Render multiple components with a single ternary operator

If currentProfiles.length > 0, I'd like to map over an array named profiles and render a profile component for each profile, and render a pagination component below the profiles. I tried this with a single ternary operator, but this results in only the pagination component being rendered.
{currentProfiles.length > 0 ? (
(currentProfiles.map(profile => (
<ProfileItem key={profile._id} profile={profile} />
)),
(
<Pagination
profilesPerPage={profilesPerPage}
totalProfiles={profiles.length}
/>
))
) : (
<Spinner />
)}
If I use two separate ternary operators, I get the list of profiles and pagination as expected, but can I do both things with a single conditional operator?
Your code just needs some restructuring. If you wrap the mapped profiles and pagination components in a parent fragment or other element, it's easy. Note, too, that the first example below still retains the ternary, as requested.
return (
<div className="App">
{currentProfiles.length ? (
<>
{currentProfiles.map(p => (
<Profile {...p} />
))}
<Pagination profilesPerPage={2} totalProfiles={totalProfiles} />
</>
) : (
<p>Loading...</p>
)}
</div>
);
However, you have a few options aside from wrapping them in a non-rendered Fragment or its shorthand derivative. You could also use an actual element, such as a div. Or even omit the parent entirely and place your logic within an array, as in:
<div className="App">
{currentProfiles.length ? [
currentProfiles.map(p => (
<Profile {...p} />
)),
<Pagination profilesPerPage={2} totalProfiles={totalProfiles} />
] : <p>Loading...</p>}
</div>
Always remember that, unless you utilize the second approach, you'll need to ensure siblings share a common parent.
Working example.
You can use an array or a fragment https://reactjs.org/docs/fragments.html
{currentProfiles.length > 0 ? (
<>
currentProfiles.map(profile => (
<ProfileItem key={profile._id} profile={profile} />
)
<Pagination
profilesPerPage={profilesPerPage}
totalProfiles={profiles.length}
/>
</>
) : (
<Spinner />
)}

Two imports div in map()

I am thinking about the possibility of embedding two imports among map().
My react code looks like this:
{this.state.dataExample.map(item => (
<ItemsSection nameSection={item.name} />
item.data.map((post, index) => (
<ItemsTasks
key={index}
title={post.name}
/>
))
))}
result:
// from ItemsSection
<div className="items-section-name">
<div className="section-name">{nameSection}</div>
</div>
// from ItemsTasks
<div className="item-data">
<div className="item-title">{title}</div>
<div className="item-data">
<div className="item-title">{title}</div>
</div>
This code should illustrate what I would like to get. Trying to import a separate div for each 'element'. The above code reports a syntax error but I have no idea how I could do it.
From the docs,
A common pattern in React is for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM.
You can use Fragment, short syntax <></> (It looks like empty tags),
{
this.state.dataExample.map(item => (
<>
<ItemsSection nameSection={item.name} />
{
item.data.map((post, index) => (
<ItemsTasks
key={index}
title={post.name}
/>
))
}
</>
))
}
or you can import Fragment from react package,
import React, {Fragment} from 'react';
{
this.state.dataExample.map(item => (
<Fragment>
<ItemsSection nameSection={item.name} />
{
item.data.map((post, index) => (
<ItemsTasks
key={index}
title={post.name}
/>
))
}
</Fragment>
))
}
You can use React's Fragment
{
this.state.dataExample.map(item => (
<React.Fragment>
<ItemsSection nameSection={item.name} />
{
item.data.map((post, index) => (
<ItemsTasks
key={index}
title={post.name}
/>
))
}
</React.Fragment>
))
}

Reactjs condition inside map function

I've looked at a bunch of questions here and read the docs over and over, however this just doesn't seem to want to work no matter what I do.
This is supposed to return one thing if X is true and return something else if it's not. It's inside a map function because I need this to be done for multiple things at once.
function ContentProcessing(props) {
return (
<div>
props.content.map(content => {
{content.type === "card" ? (
<Card title={content.title} />
) : (
<Content title={content.title} paragraph={content.guideline} />
)}
})
</div>
);
}
both <Card /> and <Content /> return one string
However I get the error
./src/App.js
Syntax error: /src/App.js: Unexpected token, expected , (79:13)
77 | <div>
78 | props.content.map(content => {
> 79 | {content.type === "card" ? (
| ^
80 | <Card title={content.title} />
81 | ) ? (
82 | <Content title={content.title} paragraph={content.guideline} />
I don't get why this isn't working.
Issues:
1- Use {} to put expressions inside jsx (to put map inside div).
2- you are using {} means block body of arrow function, so you need to use return inside the function body, otherwise by default map returns undefined.
3- You are using {} twice, so 2nd {} will be treated as object and content.type will be treated as key and that key is not valid, thats why you are getting error.
4- Forgot to define the key on elements.
Use this:
return (
<div>
{
props.content.map(content => content.type === "card" ? (
<Card title={content.title} />
) : (
<Content title={content.title} paragraph={content.guideline} />
)
)}
</div>
);
A couple of things are wrong I believe. You didn't add the curly braces in the first div. Inside the map you added two times the curly braces so you either remove one or add a return statement. You also added to "?" (the second one should be ":").
This should work:
function ContentProcessing(props) {
return (
<div>
{props.content.map(content =>
content.type === "card" ? <Card title={content.title} /> : <Content title={content.title} paragraph={content.guideline} />
)}
</div>
);
}
You can also add if else statements inside the map if you add braces:
function ContentProcessing(props) {
return (
<div>
{props.content.map((content) => {
if (content.type === "card") {
return (<Card title={content.title} />);
}
return (<Content title={content.title} paragraph={content.guideline} />);
})}
</div>
);
}
Your syntax for the ternary operator is wrong. You have condition ? a ? b. The correct syntax is condition ? a : b.
Try
function ContentProcessing(props) {
return (
<div>
{props.content.map(content =>
content.type === "card" ? (<Card title={content.title} />) :
(<Content title={content.title} paragraph={content.guideline} />)
)}
</div>
);
}
Multiple issues with the code.
return (
<div>
{props.content.map(content =>
content.type === "card" ? (
<Card title={content.title} />
) : (
<Content title={content.title} paragraph={content.guideline} />
)
)}
</div>
);
Extra brackets removed.
Conditional operator syntax was wrong.expression ? expression : expression

Categories