Search code examples
javascriptreactjsreact-reduxreact-modalreact-slick

Sending relative data from mapped array into a modal?


Demonstration of what should happen

So I have mapped data from array into a carousel, creating total of twenty carousel items. Each element has "same" button embedded into them. I want to send the relative data from each element into the modal when that button is clicked and honestly I have no idea even where to start from.

This is the code I have currently for this component:

Edit: highlighted the data I would like to pass into the relative modal.

    import React from 'react';
    import {connect} from 'react-redux';
    import Slider from 'react-slick';
    import Modal from 'react-modal';

    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

    import { fetchActionM } from '../../store/actions/moviepageActions';

    const img_url = 'https://image.tmdb.org/t/p/original';

    const customStyles = {
        content : {
          top                   : '50%',
          left                  : '50%',
          right                 : 'auto',
          bottom                : 'auto',
          marginRight           : '-50%',
          transform             : 'translate(-50%, -50%)',
          color                 : 'white',
          background: '#080a0a none repeat scroll 0% 0%',
          width: '600px',
        }
    };

    Modal.setAppElement('#root')

    class ActionMov extends React.Component{
        constructor() {
            super();

            this.state = {
                modalIsOpen: false
            };

            this.openModal = this.openModal.bind(this);
            this.afterOpenModal = this.afterOpenModal.bind(this);
            this.closeModal = this.closeModal.bind(this);


        }

        openModal() {
            this.setState({modalIsOpen: true});
        }

        afterOpenModal(){
            this.subtitle.style.color = '#f00';
        }

        closeModal(){
            this.setState({modalIsOpen: false});
        }

        render(){
        //send same mapped data from this into the modal when clicked on the button <FontAwesomeIcon onClick....
        let action;
        if(this.props.action.length > 0){
            action = this.props.action[0].results.map(ac => (
                <div className='sliderbox' key={ac.id}>
                    <div className='text-block'>
                        <h5 className='sliderTitle'>{ac.title}</h5>
                        <FontAwesomeIcon onClick={() => this.openModal({ac})} icon="plus-circle" className='sliderIcon' />

{/* I need same data from these two be passed into the relative modal */}

                        <p className='sliderRelease'>{ac.release_date}</p>
                        <p className='sliderVote'>{ac.vote_average}</p>

{/* Just highlighting this area */}

                    </div>
                    <img className='sliderImg' src={`${img_url}${ac.poster_path}`} alt={ac.title} />
                </div>
            ));
        }

        const settings = {
            dots: true,
            infinite: true,
            speed: 500,
            slidesToShow: 6,
            slidesToScroll: 3,
            draggable: true,
        };
            return (
                <div>
                    <Slider {...settings}>
                        {action}
                    </Slider>
                    <Modal
                    isOpen={this.state.modalIsOpen}
                    onAfterOpen={this.afterOpenModal}
                    onRequestClose={this.closeModal}
                    style={customStyles}
                    contentLabel='Movies modal'
                    >
                    {
                        //Would like to print relative data here
                    }
                    <h2 ref={subtitle => this.subtitle = subtitle}>TITLE GOES HERE</h2>
                        <div>
                        <p>Id: {`<id goes here>`}</p>
                        <h5 className='modalRelease'>Released: {`<release date goes here>`}</h5>
                        <h5 className='modalVote'>Rating: {`<rating goes here>`}</h5>
                        </div>
                    <button className='modalClose' onClick={this.closeModal}>X</button>
                    </Modal>
                </div>
            )
        }
    }

    const mapStateToProps = (state) => {
        return {
            action: state.movies.actions
        }
    }

    export default connect(mapStateToProps)(ActionMov);

Solution

  • On click of the button you can set it to the state and can access inside the modal. First let's initialize it inside the constructor

    constructor() {
            super();
            this.state = {
                modalIsOpen: false,
                movie: {
                   id: '', release: '', rating: ''
            }
        };
    
        this.openModal = this.openModal.bind(this);
        this.afterOpenModal = this.afterOpenModal.bind(this);
        this.closeModal = this.closeModal.bind(this);
    
    
    }
    

    Now lets set it up on onClick event, you are actually passing the object to openModal method

    openModal(movie) {
            this.setState({
               modalIsOpen: true,
               movie: movie
            }); 
    }
    

    Now you are good to access it inside the modal

    <Modal
        isOpen={this.state.modalIsOpen}
        onAfterOpen={this.afterOpenModal}
        onRequestClose={this.closeModal}
        style={customStyles}
        contentLabel='Movies modal'
    >
        {
            //Would like to print relative data here
        }
        <h2 ref={subtitle => this.subtitle = subtitle}>TITLE GOES HERE</h2>
        <div>
            <p>Id: {this.state.movie.id}</p>
            <h5 className='modalRelease'>Released: {this.state.movie.release}</h5>
            <h5 className='modalVote'>Rating: {this.state.movie.rating}</h5>
        </div>
        <button className='modalClose' onClick={this.closeModal}>X</button>
    </Modal>