I have a grid with many items, and would like each item to open its own modal when clicked (i.e. a zoomed in photo). Is there a way to do this so that instead of rendering a bunch of modals, we only need to create a single one that renders the proper content?

I would dynamically generate the content of a single modal based on the link that was clicked. As an example, you can see what I did for the React Rally schedule on our website https://github.com/react-rally/www/blob/gh-pages/2015/app/screens/Schedule/index.js#L152-L180
So it seems that @mzabriskie is suggesting making the parent component of your grid items the owner of the modal and having clicks on the grid items invoke a callback to the parent to render the appropriate content in the modal. This would work, but I find it less than ideal simply because it introduces a callback dependency that could be avoided.
It would be nice to be able to configure whether the ReactModalPortal element is inserted into the DOM if the modal is not the open state, which would effectively solve this problem (though I can imagine possible performance considerations where you'd want the option). You can accomplish the same by conditionally rendering the modal, something like this:
render() {
return (<div>
{'some component content'}
{this.state.modalIsOpen ?
<Modal
isOpen={this.state.modalIsOpen}
onRequestClose={this.closeModal}>
{'some modal content'}
</Modal>
: null}
</div>);
}
@pumpikano - great solution. It works :smile: Thank you
@claydiffrient How would do this in my case ?
This is my Grid.js
export default class Grid extends React.Component {
showmodal(){
// do whatever to show modal
}
render() {
let data = [
{id:1, name: 'john', star: 4},
{id:2, name: 'peter', star: 1},
{id:3, name: 'sasa', star: 3}
]
return (
<div>
{
data.map( function(i, index){
return (
<div className="item" onclick={this.showmodal}>
<span>{i.id}</span>
<span>{i.name}</span>
<span>{i.star}</span>
</div>
)
})
}
<Modal
overlayClassName="detail-modal-overlay"
className="detail-modal"
isOpen={this.state.detailModal}
onRequestClose={this.closeDetailModal.bind(this)}>
</Modal>
</div>
)
}
}
What I want is, when an item is clicked, the modal will display the content as below:
<div>
<span>{...clicked id..}</span>
<span>{...name of clicked id...}</span>
<span>{...star of clicked id...}</span>
</div>
This 'issue' is old but one year later I have to thanks @mzabriskie for sharing that repository. Because of it I was able to implement a similar dynamic modal to my project. Your code was really clear and I was able to understand what you were doing. Had some troubleshooting in my project but it was because of my javascript limitations but it was like looking at a tutorial without an order or explanation of things.
Most helpful comment
So it seems that @mzabriskie is suggesting making the parent component of your grid items the owner of the modal and having clicks on the grid items invoke a callback to the parent to render the appropriate content in the modal. This would work, but I find it less than ideal simply because it introduces a callback dependency that could be avoided.
It would be nice to be able to configure whether the
ReactModalPortalelement is inserted into the DOM if the modal is not the open state, which would effectively solve this problem (though I can imagine possible performance considerations where you'd want the option). You can accomplish the same by conditionally rendering the modal, something like this: