Rajat Rajat - 3 months ago 39
React JSX Question

Simple Carousel Component in React

API that I am trying to design:

<Carousel>
<CarouselItem><any arbitrary HTML here></CarouselItem>
<CarouselItem><any arbitrary HTML here></CarouselItem>
<CarouselItem><any arbitrary HTML here></CarouselItem>
</Carousel>





Each
<CarouselItem/>
is supposed to have a
next
button, So, my
<CarouselItem/>
render function looks like this:

<div className="carousel-item">
{this.props.children}
<div onClick={this.nextSlide}>
Next
</div>
</div>


My
<Carousel/>
component's job is to render only 1
CarouselItem
at a time and jump to the next one when a click happens.

I am able to render a single
CarouselItem
but I am having trouble wiring up a click handler to the
CarouselItem
inside
Carousel


import React, { Component } from 'react'
import CarouselItem from './carousel-item'

class Carousel extends Component {
constructor(props, context) {
super(props, context)

this.state = {
currentIndex: -1,
currentItem: null
}

this.activateSlideAtIndex = this.activateSlideAtIndex.bind(this)
}

findItemAtIndex(index) {
return this.props.children.find((carouselItemComponent)=> carouselItemComponent.props.item.index === index)
}

componentWillMount() {
this.activateSlideAtIndex(this.state.currentIndex)
}

activateSlideAtIndex(index) {
let newCarouselItemComponent = this.findItemAtIndex(index+1)
if (newCarouselItemComponent) {
newCarouselItemComponent.props.onClick = this.activateSlideAtIndex
//Complains here that Cannot assign to read only property 'onClick' of object '#<Object>'
this.setState({
currentIndex: index+1,
currentItem: newCarouselItemComponent
})
}
}

render() {
return (
<div className="carousel">
{this.state.currentItem}
</div>
)
}
}

export default Carousel


I understand that I cannot override the
props
of a child component. How am I supposed to achieve what I want then? All help is appreciated.

Answer

I wouldn't store the entire selected component in state, I would store the selected index and then render based off that. Something like:

render() {
  <div>
    {this.props.children[this.state.currentIndex]}
  </div>
}

hm but in terms of adding to the props of those children.. it looks like this article discusses it.

Comments