Reputation: 683
I have problem with react-modal. I have list of SingleElement
and after click it should appear modal window with more details of clicked element. JSON with data is stored as state and from the inside of Modal I can't find way to get desired element.
Here's the modal inside render()
function:
<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>
And here are methods responsible for showing/hiding modal window:
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});
}
Upvotes: 1
Views: 7686
Reputation: 49749
So what I understand is you rendered each item in the state.elements and each <SingleElement/>
component has a button and upon clicking on this button you want to open the modal will display the value of single element.
Looks like each button is going to use the openModal
method. With this method we have to do 2 things. First change the this.state.modalIsOpen
value and pass the dynamic value on to the modal body. For this, first I'll show you a javascript magic.
In JavaScript:
!!undefined=false
!!anystring=true // pretty clear I believe
So first step, this.state.modalIsOpen:undefined
should be set like so. The magic will start in the third step.
The second step is you have to pass this value to the singleModal
component. In your parent component you also render a component that includes Modal so I will name it **singleModal**.
<singleModal modalIsOpen={this.state.modalIsOpen}/>
Third step in the Modal component I believe it is a stateless function component.
<Modal isOpen={!!props.modalIsOpen} />
Initially in the state the modalIsOpen
value was undefined.
So with JavaScript magic !!props.modalIsOpen
value is set to false. So no modal shows up.
Fourth step, openModal
method activates the modal:
openModal = (beerId) => {
this.setState({
modalIsOpen: this.state.elements[beerId],
chosenBeer: this.state.beers[beerId]});
})
}
Since I don't know anything about the layout about your app, I assumed that beerId
is same as the key id value inside each <SingleElement key={} />
. So I pulled the single element inside the this.state.elements
.
Here is the second part of the magic: I set the modalIsOpen
to this.state.elements[beerId]
. Remember that this value is what we set for the isOpen
prop inside the Modal component.
<Modal isOpen={!!props.modalIsOpen}/>
This time props.modalIsOpen=this.state.elements[beerId]
which is a string. so !!props.modalIsOpen
will be true and your modal will open.
Last step, now inside the modal:
{props.modalIsOpen && <p>{props.modalIsOpen}</p>}
Upvotes: 0
Reputation: 1867
You can do this two ways. When a menu item is clicked created a function that stores the menu item to the state, then the modal can call directly from the state.
What I would do, is have a function attached to the listItem that captures the selected item and sends it through to a custom reusable modal component...
onClick={() => this.handleClick(item)}
handleClick(item) {
//You would need to create a reusable modal component and import it.
return (
<ReusableModalComponent item={item}
)
}
Then in your ReusableModalComponent you can access everything from the list via this.props.item.src...etc
Update for your example to make your code work as is...
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}) />)
})
Then, reference this.state.itemToShow.etc inside your modal
Upvotes: 1