React, conditional rendering inside map method - javascript

I have the following code and I want to apply a conditional rendering, because the index 0 does not exist. I don't want to render the information for this particular index. How can I do it?
return (
<section>
{pokemonCards.map((pokemon, index) =>
<div key={index}>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index}.png`}
alt={pokemon.name}/>
<p>{pokemon.name}</p>
</div>
)}
<button
className="get-more-button"
onClick={getMorePokemons}>Get more pokemons
</button>
</section>
)

This should work:
return (
<section>
{pokemonCards.map((pokemon, index) =>
{index === 0 ? null : <div key={index}>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index}.png`}
alt={pokemon.name}/>
<p>{pokemon.name}</p>
</div>
)}
<button
className="get-more-button"
onClick={getMorePokemons}>Get more pokemons
</button>}
</section>
)

You could do as below if you do not want to render an empty div for the nonexisting pokemon:
return (
<section>
{pokemonCards.map(
(pokemon, index) =>
index !== 0 && (
<div key={index}>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index}.png`}
alt={pokemon.name}
/>
<p>{pokemon.name}</p>
</div>
)
)}
<button className="get-more-button" onClick={getMorePokemons}>
Get more pokemons
</button>
</section>
);

Related

React change icon onClick from loop

I included an Icon while mapping an array and I need to change the icon on that specific iteration onclick, I also want to render the test results when the icon is clicked.
I'm not sure how to get a unique value that is specific to this iteration that will handle this change or is my structure all wrong?
** went to sleep found solution = encapsulation **
map the component so the boolean variable is local scoped to that iteration.
shared solution below
const Students = ({students}) => {
const [showTests, setShowTests] = useState(false);
return (
<div className="wrapper" key={student.id}>
<div className="img-container">
<img src={student.pic} alt="student" />
</div>
<div className="content">
<h1>
{student.firstName.toUpperCase()} {student.lastName.toUpperCase()}
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>Average: {averageGrade(student.grades)}%</p>
{showTests && <TestResults results={student.tests} />}
</div>
{showTests ? (
<FontAwesomeIcon
onClick={() => setShowTests(!showTests)}
className="faIcon"
icon={faMinus}
/>
) : (
<FontAwesomeIcon
onClick={() => setShowTests(!showTests)}
className="faIcon"
icon={faPlus}
/>
)}
</div>
);
}
const Main = () => {
return (
<div className="main" id="main">
{filteredStudents.map(student => (
//each iteration is a unique component
<Students student={student} />
))}
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Thanks ahead of time for any suggestions
The return must always have a top-level tag.
const Students = ({ students }) => {
return (
<>
{students.map((student, i) => (
<div className="wrapper" key={student.id}>
<div className="img-container">
<img src={student.pic} alt="student" />
</div>
<div className="content">
<h1>
{student.firstName.toUpperCase()}{" "}
{student.lastName.toUpperCase()}
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>Average: {averageGrade(student.grades)}%</p>
{faMinus && <TestResults results={student.tests} />}
</div>
<FontAwesomeIcon
id={i}
onClick={(e) => handleTests(e.target.id)}
className="faIcon"
icon={current ? faPlus : faMinus}
/>
</div>
))}
</>
);
};
Let me know if this is what you're thinking. Just store the index in a state variable and compare against it. When they click change the index to the one they clicked on.
const Students = ({students}) => {
const [selectedIndex, setSelectedIndex] = useState(0)
function handleTests(id, index) { //NEW
//Your current code
setSelectedIndex(index) //NEW
}
return (
{students.map((student, i) => (
<div className="wrapper" key={student.id}>
<div className="img-container">
<img src={student.pic} alt="student" />
</div>
<div className="content">
<h1>
{student.firstName.toUpperCase()} {student.lastName.toUpperCase()}
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>Average: {averageGrade(student.grades)}%</p>
{selectedIndex == i && <TestResults results={student.tests} />} //NEW
</div>
<FontAwesomeIcon
id={i}
onClick={e => handleTests(e.target.id, i)} //NEW
className="faIcon"
icon={selectedIndex == i ? faPlus : faMinus}
/>
</div>
))}
)
}

Are nested conditional renderings possible with REACT?

I am trying to achieve the following for a special page
const Pricing = () => {
return (
<main class="o-main">
<section class="plan">
<div class="plan">
<div class="plan">
<h1 class="plan">Select the best plan</h1>
<p class="plan">from plan1 to plan3</p>
</div>
</div>
</section>
<div class="plan">
<div class="plan">
<h1 class="plan">features</h1>
<p class="plan">features of plan1</p>
</div>
</div>
{isLoggedin() ? (
{userPlan() === 'plan1' ? (
<FaCheckCircle />
<a class="plan">current plan</a>
) : (
<a class="plan" onClick={() => {...}}>sign up</a>
)}
) : (
sign up
)}
<div class="plan">
<div class="plan">
<h1 class="plan">features</h1>
<p class="plan">features of plan2</p>
</div>
</div>
{isLoggedin() ? (
<>
{userPlan() === 'plan2' ? (
<>
<FaCheckCircle />
<a class="plan">current plan</a>
</>
) : (
<>
<a class="plan" onClick={() => {...}}>upgrade to plan2</a>
</>
)}
</>
) : (
<>
sign up
</>
)}
<div class="plan">
<div class="plan">
<h1 class="plan">features</h1>
<p class="plan">features of plan3</p>
</div>
</div>
{isLoggedin() ? (
<>
{userPlan() === 'plan3' ? (
<>
<FaCheckCircle />
<a class="plan">current plan</a>
</>
) : (
<>
<a class="plan" onClick={() => {...}}>upgrade to plan3</a>
</>
)}
</>
) : (
<>
sign up
</>
)}
</main>
);
};
export default Pricing;
userPlan() is a function of fetch API call that returns a string like plan1 or plan2
but i am getting the following error
Syntax error: Unexpected token
{userPlan() === 'plan1' ? (
^
anything am missing or the logic is not possible in react?
before using this function's return value , check if it is available:
isLoggedin() && userPlan() ? ...
issue was that here is what is what i really had
{isLoggedin() ? (
{userPlan() === 'plan1' ? (
<FaCheckCircle />
<a class="plan">current plan</a>
) : (
<a class="plan" onClick={() => {...}}>sign up</a>
)}
) : (
sign up
)}
and here is what worked and removed the syntax error
{isLoggedin() ? (
<>
{userPlan() === 'plan1' ? (
<>
<FaCheckCircle />
<a class="plan">current plan</a>
</>
) : (
<>
<a class="plan" onClick={() => {...}}>sign up</a>
</>
)}
</>
) : (
<>
sign up
</>
)}
the thing is sometimes it does not complain about the <> and </> and sometimes it does, in this case
anyone that knows why this is inconsistent, please comment below

Data from mapped object onClick - React

can you help me how can I get genre.id when user clicks on Button onClick function ?
Thank you
...
return (
<div className="App">
<Header />
<div className="App-wrapp">
<div className="filter">
{osa &&
osa.map((genre) => (
<Button key={genre.id} {...genre} onClick={thisFunction} />
))}
</div>
<div className="movie-list">
{movies.length > 0 &&
movies.map((movie) => <Movie key={movie.id} {...movie} />)}
<button className="btn" onClick={showMore}>
Load More
</button>
</div>
</div>
</div>
);
}
export default App;
<Button key={genre.id} {...genre} onClick={() => thisFunction(genre.id)} />

TypeError: Cannot read property '0' of null, react-fullpage

<div className="left">
<ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
{this.state.items == undefined ? '' : this.state.items.map((img,i) => (
<img className="section" key={i} src={img.image}></img>
))}
</div>
);
}}
/>
</div>
Hi, I've some issues when I am trying to fetch the data and render in ReactFullpage Component, the error says:
TypeError: Cannot read property '0' of null
Thank you, all help is welcome.
The issue here is that ReactFullPage works on the principle of finding a className section in one of the rendered elements
Now since you load your items async, initially the following content is rendered
return (
<div id="fullpage-wrapper">
{''}
</div>
);
Notice that it doesn't have a className section to it and it throws you the error
The solution here is to either wait for items to load before showing ReactFullPage
<div className="left">
{this.state.items && <ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
{this.state.items.map((img,i) => (
<img className="section" key={i} src={img.image}></img>
)}
</div>
);
}}
/>}
</div>
or return a dummy component to ReactFullPage
<div className="left">
<ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
{this.state.items == undefined ? <div className="section" /> : this.state.items.map((img,i) => (
<img className="section" key={i} src={img.image}></img>
))}
</div>
);
}}
/>
</div>

React map - don't return item if missing

I'm using map in react to show a feed of facebook posts, but i don't want the post to render if the message field is missing from the json data.
If I do this I get an error ('if' is an unexpected token) and my project won't build
return (
<Slider
{...Settings}>
{postsAvailable && posts.map((post, index) => (
if (!post.message) return null
return (<div key={post.id}>
{ index === 0 && <Item /> }
{ index > 0 && <div className='item'>
<img data-original={post.full_picture} className='img-responsive' />
<div className={`facebook-content slide-${post.id}`}>
<p className='text'>{post.message}</p>
</div>
</div> }
</div>)
))}
</Slider>
)
You can use filter first:
posts.filter((post) => post.message).map((post, index) => (...
Although, if possible you should filter when you get the posts, and not in the render function. Do as little as possible in the render function - for a good overview, and for performance.
You are not giving your function given to map a body. Change () to {} and it will work as expected.
return (
<Slider {...Settings}>
{postsAvailable &&
posts.map((post, index) => {
if (!post.message) return null;
return (
<div key={post.id}>
{index === 0 && <Item />}
{index > 0 && (
<div className="item">
<img
data-original={post.full_picture}
className="img-responsive"
/>
<div className={`facebook-content slide-${post.id}`}>
<p className="text">{post.message}</p>
</div>
</div>
)}
</div>
);
})}
</Slider>
);
Alternatively you could filter out all the posts that don't have a message first and then map those that does.
return (
<Slider {...Settings}>
{postsAvailable &&
posts
.filter(post => post.message)
.map((post, index) => (
<div key={post.id}>
{index === 0 && <Item />}
{index > 0 && (
<div className="item">
<img
data-original={post.full_picture}
className="img-responsive"
/>
<div className={`facebook-content slide-${post.id}`}>
<p className="text">{post.message}</p>
</div>
</div>
)}
</div>
))}
</Slider>
);

Categories

Resources