How to append "active" class on first div using loop in Reactjs - javascript

I am working in Reactjs and using nextjs framework,right now i fetching data (videos) in slider and i want by default "active class" should be added to first value of array, In other words before click on slide i want by default value should "active" and should remove after click on "slide arrow" (< or >) button,How can i do this ? Here is my code
{this.state.trending.map((post, index) => {
return (
<>
<div class="carousel-item active">
<YouTube videoId={post.VideoId} opts={opts} />
</div>
</>
)
})}

This should work:
{this.state.trending.map((post, index) => {
return (
<>
<div class={`carousel-item ${index===0 ? "active" : ""`}>
<YouTube videoId={post.VideoId} opts={opts} />
</div>
</>
)
})}

Related

React Nested Foreach on Return

Trying to use nested foreach in React.
But not working at all;
return (
{category.map((item, i) => (
<div className="col-sm-12">
<h5>{item.title}</h5>
</div>
item.data.map((it, iv) => (
<div class="col-6">
<ProductCard {...it} />
</div>
))
))}
)
You are using .map higher order function
you need to wrap in in fragment so React Will know that it's a JSX or wrap it on div
Introduction to JSX
Learn Fragment React
return (
<>
{category.map((item, i) => (
<div className="col-sm-12">
<h5>{item.title}</h5>
</div>
item.data.map((it, iv) => (
<div class="col-6">
<ProductCard {...it} />
</div>
))
))}
</>
)
if you want to render nested array maybe it will work
return (
<> // Put Wrapper
{category.map((item, i) => (
<> // put an empty fragment to contain title div and another map
<div key={i} className="col-sm-12"> // dont forget to put key props
<h5>{item.title}</h5>
</div>
{item.data.map((it, iv) => ( // wrap another map on '{}' because it inside jsx
<div key={iv} class="col-6"> // dont forget to put key props
<ProductCard {...it} />
</div>
)}
</>
)}
</>
)
you can also change <> to div or any if you want to style it. And dont put // comment on jsx, it just my mark to explain this code

Conditional styling in react map

I only want to show the display block on the hovered item. but when I hover it shows on every item in a map function. what I'm doing wrong.
basically, I just want to show hovered movie item's title. for now, it shows every movie when I hover.
MovieList.js
const [popular, setPopular] = useState([]);
const [hover, setHover] = useState(false);
return (
<>
<div className="movie-list">
<h2 style={{ fontSize: "49px", marginLeft: "60px" }}>What's Popular</h2>
<div className="popular">
{popular.map((pop, index) => (
<>
<div className="movie" key={index}>
<div className="tot" onMouseEnter={() => setHover(true)}>
<h4
id="pop-title"
style={{ display: hover ? "block" : "none" }}
key={index}
>
{pop.title}
</h4>
</div>
<img
src={"https://image.tmdb.org/t/p/w500" + pop.poster_path}
id="movie-img"
/>
</div>
</>
))}
</div>
</div>
</>
);
};
export default MovieList;
The same hover state variable is used for all your movies, so when it becomes true, all the movies are affected by the change. You could use something like an object instead of just a boolean to store one hover state per movie.
Another problem with your code that isn't helping:
You are missing a unique key prop on each item of the map (it must be on the direct child).
Solution 1: Remove the Fragment
Everything is already under one div so you don't need the React Fragment (<>) in that case. Also, you might wanna use something unique to the current map item other than the index in the array.
{popular.map((pop) => (
<div className="movie" key={pop.somethingUnique}>
<div className="tot" onMouseEnter={() => setHover(true)}>
<h4 id="pop-title" style={{ display: hover ? "block" : "none" }}>
{pop.title}
</h4>
</div>
<img
src={"https://image.tmdb.org/t/p/w500" + pop.poster_path}
id="movie-img"
/>
</div>
))}
Solution 2: Set the key on the Fragment
{popular.map((pop) => (
<Fragment key={pop.somethingUnique}>
<div className="movie">
<div className="tot" onMouseEnter={() => setHover(true)}>
<h4 id="pop-title" style={{ display: hover ? "block" : "none" }}>
{pop.title}
</h4>
</div>
<img
src={"https://image.tmdb.org/t/p/w500" + pop.poster_path}
id="movie-img"
/>
</div>
</Fragment>
))}

react bootstrap carousel Items "Each child in a list should have a unique "key" prop"

Bootsrap carousel Items unique key error.i added the right place my key.but error won't go away.
here is my error.
when i inspect in elements,i think i added to the right place.but react giving me warning over and over again.
this is my code.
return (
<>
<Carousel activeIndex={index} onSelect={handleSelect} keyboard slide touch wrap pause={false}>
{movie.map((m) =>
<Carousel.Item key={m.id}>
<img
src={m.background_image_original}
alt={m.title_english}
/>
<Carousel.Caption>
<CaptionDiv >
<h4>suggestions</h4>
<h2>{m.title}</h2>
<CaptioninfoDiv className='mr-auto'>
<p className='mr-3'>{m.year}</p>
{m.genres.map((g) =>
<p className='mr-1'>{g}</p>
)}
<p className='ml-3'>{m.runtime} min</p>
</CaptioninfoDiv>
<CaptionInfoMain >
<p>{m.summary.slice(0, 200)}<Readmore> Read more...</Readmore> </p>
<a href={`https://www.youtube.com/watch?v=${m.yt_trailer_code}`} target="_blank" rel="noreferrer" className='btn btn-danger btn-lg'>Watch Trailer</a>
</CaptionInfoMain>
</CaptionDiv>
</Carousel.Caption>
</Carousel.Item>
)}
</Carousel>
</>
)
Your movie.map((m) => is giving keys to its children, but your m.genres.map((g) => is not. Assuming that there aren't any duplicate generes, you can use
{
m.genres.map((g) =>
<p className='mr-1' key={g}>{g}</p>
)
}

react-beautiful-dnd: Prevent the rest of draggable items from reordering / moving up and replacing the item being dragged

In a single Droppable, I have mapped out an array of items, each as its own Draggable. My code is working properly and is doing what it's supposed to (i.e., I can move each Draggable individually). I'm just wondering if there's a way to stop the rest of my Draggables from "moving up" or replacing the empty spot the item-that's-being-dragged leaves behind.
Here's my code (DragDropContext is in another component, so it's not shown here):
<Droppable
droppableId='itemDroppable'
type='acceptsItems'
isDropDisabled={true} >
{(provided) =>
<div ref={provided.innerRef}>
{this.props.items.map((item, index) =>
<Draggable
key={item.id}
draggableId={item.name}
index={index} >
{provided =>
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps} >
{item.icon}
</div>
}
</Draggable>
)}
{provided.placeholder}
</div>
}
</Droppable>
And here's a video of what's happening:
As you can see, the rest of the following icons move up and replace the empty spot left by the item that's being dragged out of the Droppable. Is there a way to stop this? Ideally, I'd like to have the empty spot stay empty and not have the rest of the proceeding icons move up and fill up.
Thank you in advance!
I don't have a direct solution but I have an idea that may work around this problem.
when you are displaying the items using Array.map() function
first: suppose we add some additional information to the object to track if it's deleted.
add a condition so It renders the element if the flag is true.
Otherwise, a hidden element will be displayed.
note: I not sure but I think you can use provide.placeholder
for example:
{(provided) => (
<div ref={provided.innerRef}>
{this.props.items.map((item, index) => {
if (item.id !== 0) {
return (
<Draggable
key={item.id}
draggableId={item.name}
index={index}
>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{item.icon}
</div>
)}
</Draggable>
);
} else
return (
<div style={{ width: '20px', height: '20px' }} /> //display hidden undraggable hidden element or try provided.placeholder
);
})}
{provided.placeholder}
</div>
)}
second: when you implement the deleting function inside onDragEnd() we can change the flag of that element.

How to use reactive search to achieve 'Load More' function?

I want to build a searching page with Reactive search, and when users scroll the search results to the bottom, they can find a "Load More" button, by clicking it, the next page will be loaded. I found that in the document, there is a callback function called "handleLoadMore()", but I don't know how to use it.
The code I wrote is just like this.
<ReactiveList
className={classes.content}
dataField={"description"}
componentId={"SearchResult"}
react={{ and: ["DataSearch"] }}
pagination={false}
scrollOnChange={true}
stream={true}
showResultStats={true}
renderResultStats={stats => {
return (
<div>
<p className={classes.stats}>
{stats.numberOfResults} results available based on your location
</p>
<img
className={classes.logo_color}
src={require("../../images/logo-color.png")}
alt="logo-color"
/>
</div>
);
}}
paginationAt="bottom"
size={12}
infiniteScroll={true}
loader="Loading Results.."
>
{({ data, handleLoadMore }) => {
return (
<ResultCardsWrapper className={classes.cardsWrapper}>
{data.map((element, index) => {
console.log(data);
return (
<ResultCard className={classes.card} key={index} target={"_self"}>
<Link
className={classes.wrapper}
to={`/shop/${element._index}/${element._id}`}
>
<ResultCard.Image
className={classes.image}
src={getLogo(element.logo)}
/>
<ResultCard.Title className={classes.title}>
{element.title}
<div className={classes.shopIcons}>
{console.log(element.opening_hour[curDay].open)}
{curTime <= element.opening_hour[curDay].close &&
curTime >= element.opening_hour[curDay].open ? (
<img
src={require("../../images/Icon ionic-md-time.svg")}
alt="open"
/>
) : (
<img
src={require("../../images/Icon ionic-md-time-closed.svg")}
alt="open"
/>
)}
<img
src={require("../../images/Icon material-local-offer.svg")}
alt="offer"
/>
</div>
</ResultCard.Title>
</Link>
</ResultCard>
);
})}
<button onClick={handleLoadMore}>Load More</button>
</ResultCardsWrapper>
);
}}
</ReactiveList>;
you can replace the handleLoadMore to loadMore, it works for me.

Categories

Resources