Динамически изменяющийся контент в модальном режиме

У меня проблема с модальным реагированием. У меня есть список SingleElement, и после щелчка должно появиться модальное окно с более подробной информацией о выбранном элементе. JSON с данными хранится как состояние, и изнутри Modal я не могу найти способ получить нужный элемент.

Вот модальная функция внутри render():

        <Modal
            isOpen={this.state.modalIsOpen}
            onAfterOpen={this.afterOpenModal}
            onRequestClose={this.closeModal}
            chosenBeer={this.state.chosenBeer}
        >
            <h2> == Dynamically changing title of element == </h2>
            <button onClick={this.closeModal}>X</button>
            <img src="{ == Dynamically changing image == }" />
        </Modal>

        <div id="splashElements">
        {
            this.state.elements &&
            this.state.elements.map((item, index) => {
                return(<SingleElement key={index} name={item.name} href={item.href} image={item.image_url} tagline={item.tagline} onDelete={id => this.onDelete(index)} openModal={elementId => this.openModal(index)}/>)
            })
        }
        </div>

А вот методы, отвечающие за показ/скрытие модального окна:

openModal = (beerId) => {
    this.setState({modalIsOpen: true, chosenBeer: this.state.beers[beerId]});
}

afterOpenModal = () =>{
    // references are now sync'd and can be accessed.
}

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

person pkolawa    schedule 17.12.2017    source источник


Ответы (2)


Вы можете сделать это двумя словами. Когда элемент меню щелкнут, создается функция, которая сохраняет элемент меню в состояние, после чего модальное окно может вызываться непосредственно из состояния.

Что бы я сделал, так это иметь функцию, прикрепленную к listItem, которая фиксирует выбранный элемент и отправляет его в настраиваемый многоразовый модальный компонент...

onClick={() => this.handleClick(item)}

handleClick(item) {
 //You would need to create a reusable modal component and import it.
return (
<ReusableModalComponent item={item}
)

}

Затем в вашем ReusableModalComponent вы можете получить доступ ко всему из списка через this.props.item.src...etc

Обновите свой пример, чтобы ваш код работал как есть...

this.state.elements.map((item, index) => {
            return(<SingleElement key={index} name={item.name} href={item.href} image={item.image_url} tagline={item.tagline} onDelete={id => this.onDelete(index)} openModal={elementId => this.openModal(index)} onClick={() => this.setState({itemToShow: item, modalIsOpen: !this.state.modalIsOpen}) />)
        })

Затем укажите this.state.itemToShow.etc внутри вашего модального окна.

person Gavin Thomas    schedule 17.12.2017
comment
Но из-за того, что я сказал и пометил, я уже использую react-modal (компонент прямо из ReactJS GitHub) - person pkolawa; 17.12.2017
comment
Вы можете буквально скопировать и вставить модальное окно в отдельный компонент ReusableModalComponent. Затем вы держите свой код в чистоте и используете реакцию на то, как он был разработан, таким образом, вы также будете поддерживать чистоту состояния и не перекрываться с более высокими компонентами. однако я добавил обновленный фрагмент кода, который будет работать для того, что вы хотите сделать, без повторного использования модального компонента. - person Gavin Thomas; 18.12.2017

Итак, я понимаю, что вы визуализировали каждый элемент в state.elements, и каждый компонент <SingleElement/> имеет кнопку, и при нажатии на эту кнопку вы хотите открыть модальное окно, которое отобразит значение одного элемента.

похоже, что каждая кнопка будет использовать метод openModal. с этим методом мы должны сделать 2 вещи. сначала измените значение this.state.modalIsOpen и передайте динамическое значение модальному телу. для этого сначала я покажу вам магию javascript. В JavaScript

    !!undefined=false
    !!anystring=true  // pretty clear I believe

Итак, первый шаг, this.state.modalIsOpen:undefined должен быть установлен так. магия начнется на третьем шаге.

На втором шаге вы должны передать это значение компоненту singleModal. в вашем родительском компоненте вы также визуализируете компонент, который включает в себя Modal, поэтому я назову его **singleModal**.

        <singleModal
          modalIsOpen={this.state.modalIsOpen} //i just show the related prop here. 
        />

третий шаг в модальном компоненте, я считаю, что это функциональный компонент без сохранения состояния. изначально в состоянии значение modalIsOpen было undefined., поэтому с магией javascript значение !!props.modalIsOpen установлено на false. поэтому модальное окно не появляется.

четвертый шаг, метод openModal активирует модальное окно.

    openModal = (beerId) => {
    this.setState({modalIsOpen:this.state.elements[beerId] ,    chosenBeer:this.state.beers[beerId]});
      }

вот в чем дело. Поскольку я не знаю макета вашего приложения, я предположил, что пива Id совпадает со значением идентификатора key внутри каждого <SIngleElement key={} />. поэтому я вытащил единственный элемент внутри this.state.elements.

вот и вторая часть волшебства. я установил modalIsOpen на this.state.elements[beerId]. помните, что это значение мы установили для реквизита isOpen внутри модального компонента.

           <Modal
            isOpen={!!props.modalIsOpen}
          />

на этот раз props.modalIsOpen=this.state.elements[beerId], который является строкой. поэтому !!props.modalIsOpen будет true, и ваш модальный режим откроется.

Последний шаг, теперь внутри модального окна

    {props.modalIsOpen && <p>{props.modalIsOpen}</p>}
person Yilmaz    schedule 24.07.2019