Reputation: 321
I am new to ReactJS and I was wondering what is the correct way to target next element with same class in react?
<div className="portfolioGallery">
<img className="portfolioImg activeImg" src="img/1.png"/>
<img className="portfolioImg" src="img/2.png"/>
<img className="portfolioImg" src="img/2.png"/>
<div className="portfolioNext" onClick={this.nextImg.bind(this)}>
Next image
</div>
</div>
What would be the correct way that when I click the portfolioNext div I would be able to give the img2 class of activeImg and remove it from the previous element and so on in ReactJS?
Thank You!
constructor() {
super();
this.state = {
default: "portfolioImg activeImg"
};
}
nextImg() {
this.setState({
default: "portfolioImg"
});
}
Upvotes: 1
Views: 3583
Reputation: 401
I wouldn't suggest you think of it as siblings finding each other, but instead thing of it as the parent storing an index of the current children, and updating that instead.
this.props
(or this.state
) would have something like this (pseudocode)
this.props.images => ["img/1.png", "img/2.png", "img/2.png"];
Inside render:
<div className="portfolioGallery">
{this.props.images.map((image, i ) => active === i ? (<img className="portfolioImg activeImg" src="image" key={i}/>) : (<img className="portfolioImg " src="image" key={i}/>))}
<button className="portfolioNext" onClick={(e) => this.setState({active: this.state.active + 1}).bind(this)}>Next image</button>
</div>
Of course, accounting for when active >= images.length
, but you get the idea
Upvotes: 0
Reputation: 30009
That's the kind of imperative technique that you'd generally find in jQuery code, but it doesn't map very well to React's slightly more declarative nature.
Rather than trying to find the next element with a class, use state to maintain a list of those elements alongside an index cursor.
// constructor
this.state = {
images = ['img/1.png', 'img/2.png', 'img/3.png']
cursor: 0
};
Then use these bits of data to render your view.
// render
const { images, cursor } = this.state;
return (
<div>
{images.map((src, index) => {
const activeClass = (index === cursor) ? 'activeImg' : '';
return <img className={`portfolioImg ${activeClass}`} />;
}}
</div>
);
To change the active image, use setState
to change the cursor
property.
// nextImg
const { cursor, images } = this.state;
const nextCursor = cursor % images.length;
this.setState({ cursor: nextCursor });
Upvotes: 3