Search code examples
javascriptarraysreactjscarousel

Render dynamically two image carousels on the same page


Update

I have an array of objects with data and one of the key is gallery, which is an array of URLs: data=[{id:1,gallery:[]},{id:2, galery:[]}].
I did an image carousel in the mapped "data" array. The problem is that the carousels, of each item, are not independent one of each other. Each time I change the picture on one of them, it changes to the other also.
Here is the code:

export class MyComponent extends Component {
 state = {
        current: 0,
        currentItem: '',        
    }
    render() {
 const selecItem = (e) => {
            this.setState({
                currentItem: e.target.parentElement.parentElement.parentElement.id
            })
        }

        const resetSelectedItem = ()=>{
            this.setState({
                currentItem: ''
            })
        }

        const nextSlide = (e ,arr) => {
            if (this.state.currentItem !== 
e.target.parentElement
.parentElement.parentElement.id ) {
                e.preventDefault()
            } else  if (arr && 
                this.state.currentItem === e.target.parentElement
.parentElement.parentElement.id ) {
                let copy = this.state.current
                this.setState({
                    current: (copy === arr.length - 1 ? 0 : copy + 1),
                })
            }
        }

        const prevSlide = (e, arr) => {
            if (this.state.currentItem !== e.target.parentElement
.parentElement.parentElement.id ) {
                e.preventDefault()
            } else  if (arr && 
                this.state.currentItem === e.target.parentElement
.parentElement.parentElement.id ) {
                let copy = this.state.current
                this.setState({
                    current: (copy === 0 ? arr.length - 1 : copy - 1),
                })
            }
        }
       return (
         <section>                
           {data &&
              data.map((item, i) =>
                <>
                <div key={i}  id={i.toString().concat(item.id)}>
                   <div>
                    ...some data here
                   </div>
                   <div>
                      <div>
                         ...more data
                      </div>
                      <div className='carousel'  onMouseEnter={(e)=>selecItem(e)}
                            onMouseLeave={resetSelectedItem}>
                            <img src={left}
                                className='left-arrow' alt="left"
                                onClick={(e) =>this.state.currentItem 
=== i.toString().concat(data[i].id) 
                            ? prevSlide(e, data[i].gallery) : undefined} />
                            <img src={right}
                                className='right-arrow' alt="right"
                                onClick={(e) => this.state.currentItem 
=== i.toString().concat(data[i].id) 
                            ? nextSlide(e, data[i].gallery) : undefined} />
                            {data[i].gallery?.map((img, j) => (
                                <>
                                 {j === this.state.current && (
                                  <img src={img} alt={item.id} className='cart-image' key={j} />
                                    )}
                                </>
                            ))}
                    </div>
                  </div>
               </div>
            </>)}
         </section>)}}
export default MyComponent

I want to have a different carousel for each item from data array. For the moment it is working like a big one, instead of two.
For me it is strange that all the other data it is rendered the way I want.
I tried this one also:

{this.state.currentItem === i.toString().concat(data[i].id)? 
 data[i].gallery?.map((img, j) => ( 
                     <>
                       {j === this.state.current && (
                         <img src={img} alt={item.id} className='cart-image' key={j} />
                           )}
                     </>
                            ))}

In this case it is displayed and active, the carousel for only one item from data. But I want both carousels to be visible and active one at a time Could you please help me?
Thank you in advance


Solution

  • I did a new component, and I moved all the logic for the image carousel inside of this component.
    Now everything it is working fine.
    The code it is looking something like this now:

    export class MyComponent extends Component {
       render() {
         return(
           <section>                
               {data &&
                  data.map(item=>
                 <NewComponent 
                   id={item.id}
                   gallery={item.gallery} />
         )}
           </section>    
      )
     }
    }