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

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> )
}
</>)
: "-"}
</>
);

Related

React map function not assinging keys properly

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

How to simply nested ternary logic in react while rendering different component

I have the following logic inside a react component where, I am rendering different component based on the boolean values. This peace of code is very difficult to understand. Are there anyways, I can simply that logic:
{isEnabled ? (
<>
{!loading ? (
<>
{items.length === 0 ? (
<>
<ComponentOne/>
<Container>
<img src={Image} alt="Image" />
</Container>
</>
) : (
<ComponentTwo/>
)}
</>
) : (
<div>
<LoadingComponent/>
</div>
)}
</>
) : (
<ComponentThree/>
)}
I'd probably split it up into seperate components and pass parameters down the component tree for example
{isEnabled ? <IsLoadingComponent loading={loading} items={items}> : <ComponentThree/>}
You might find it useful to split the component up into a "Loading" version and a "Loaded" version so you don't have to handle both states in the same component. Then the component basically just renders the "Loading" or "Loaded" version depending on the flag.
But even without that, you can at least make that easier to debug by using if/else if etc. and assigning to a temporary variable:
let comp;
if (isEnabled) {
if (loading) {
comp = <div>
<LoadingComponent/>
</div>;
} else if (items.length === 0) {
comp = <>
<ComponentOne/>
<Container>
<img src={Image} alt="Image" />
</Container>
</>;
} else {
comp = <ComponentTwo />;
}
} else {
comp = <ComponentThree />;
}
Then just
{comp}
where that nested conditional was.
I think you are making a simple thing very complicated. What we can do instead is that make use of "&&".
{ isEnabled && loading && <LoaderComponent /> }
{isEnabled && !items.length &&
<>
<ComponentOne/>
<Container>
<img src={Image} alt="Image" />
</Container>
</>
}
{isEnabled && items.length && <ComponentTwo/>}
{!isEnabled && <ComponentThree />}
Though I want to support the argument the others made (split into multiple components), you can already achieve a bit more readability by dropping unnecessary fragments (<></>) and/or parenthesis and by using "better"(opinion) indentation.
return (
isEnabled
? loading
? <div><LoadingComponent/></div>
: items.length === 0
? <> {/* this is the only place a fragment is actually needed */}
<ComponentOne/>
<Container>
<img src={Image} alt="Image"/>
</Container>
</>
: <ComponentTwo/>
: <ComponentThree/>
);
Alternatively, early returns do help a lot with readability. For example:
const SomeComponent = () => {
// ...snip...
if (!isEnabled) {
return <ComponentThree/>;
}
if (loading) {
return <div><LoadingComponent/></div>;
}
if (items.length > 0) {
return <ComponentThree/>;
}
return (
<>
<ComponentOne/>
<Container>
<img src={Image} alt="Image"/>
</Container>
</>
);
}

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

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