admin管理员组文章数量:1332345
Hi I am playing around with ReactJS, and found this awesome Modal Component to open Videoes in a Modal, but when I put the Modal inside a loop with multiple links and open the modal, it open like 5 times if I have 5 links. What do I do wrong?
Modal Component:
import React from 'react'
import ReactDOM from 'react-dom'enter code here
import ModalVideo from 'react-modal-video'
class App extends React.Component {
constructor () {
super()
this.state = {
isOpen: false
}
this.openModal = this.openModal.bind(this)
}
openModal () {
this.setState({isOpen: true})
}
render () {
return (
<div>
<ModalVideo channel='youtube' isOpen={this.state.isOpen} videoId='L61p2uyiMSo' />
<button onClick={this.openModal}>Open</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
My Loop with the Modal Component Inside:
render(){
return(
<div>
{(this.props.frag.all == null) ? null :
this.props.frag.all.map((frags, i) => {
return (
<li key={frags.id} className="group" id="" style={{width: 'calc(13% - 30px)'}}>
<ModalVideo channel='youtube' isOpen={this.state.isOpen} videoId='{frags.url}' />
<button onClick= {this.openModal.bind(this)}>Open</button>
</li>
)})
}
</div>
Hi I am playing around with ReactJS, and found this awesome Modal Component to open Videoes in a Modal, but when I put the Modal inside a loop with multiple links and open the modal, it open like 5 times if I have 5 links. What do I do wrong?
Modal Component: https://github./appleple/react-modal-video
import React from 'react'
import ReactDOM from 'react-dom'enter code here
import ModalVideo from 'react-modal-video'
class App extends React.Component {
constructor () {
super()
this.state = {
isOpen: false
}
this.openModal = this.openModal.bind(this)
}
openModal () {
this.setState({isOpen: true})
}
render () {
return (
<div>
<ModalVideo channel='youtube' isOpen={this.state.isOpen} videoId='L61p2uyiMSo' />
<button onClick={this.openModal}>Open</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
My Loop with the Modal Component Inside:
render(){
return(
<div>
{(this.props.frag.all == null) ? null :
this.props.frag.all.map((frags, i) => {
return (
<li key={frags.id} className="group" id="" style={{width: 'calc(13% - 30px)'}}>
<ModalVideo channel='youtube' isOpen={this.state.isOpen} videoId='{frags.url}' />
<button onClick= {this.openModal.bind(this)}>Open</button>
</li>
)})
}
</div>
Share
Improve this question
asked Feb 12, 2017 at 12:12
DbTheChainDbTheChain
2352 gold badges4 silver badges13 bronze badges
3 Answers
Reset to default 5The problem is that each ModalComponent uses the same state property isOpen
so when you click on any link it sets this property and each ModalComponent bees open. You should use unique property for each modal (you can use poperty which you already uses as key
).
<li key={frags.id} className="group" id="" style={{width: 'calc(13% - 30px)'}}>
<ModalVideo channel='youtube' isOpen={this.state.isOpen[frags.id]} videoId='{frags.url}' />
<button onClick= {this.openModal.bind(this, frags.id)}>Open</button>
</li>
And your method:
openModal (id) {
this.setState({
isOpen: {
[id]: true
}
});
}
Reason is, you are using single state
variable to maintain open/close
status of modal
, it will work properly for one, but in case of multiple modals, you have to use multiple state values to maintain the statuses, Use this:
Define isOpen
as an array
in state:
this.state= {
isOpen=[],
}
Use this method to change
the status of any particular modal
:
openModal(index){
let isOpen = this.state.isOpen.slice();
isOpen[index] = true;
this.setState({isOpen});
}
Bind
the index
of each modal in onClick
method:
render(){
return(
<div>
{(this.props.frag.all == null) ? null :
this.props.frag.all.map((frags, i) => {
return (
<li key={frags.id} className="group" id="" style={{width: 'calc(13% - 30px)'}}>
<ModalVideo channel='youtube' isOpen={this.state.isOpen[i] || false} videoId='{frags.url}' />
<button onClick= {this.openModal.bind(this,i)}>Open</button>
</li>
)})
}
</div>
)
}
Modals in a loop are a bit plicated because they need a unique key for each row. Making the modal work without duplicating it is another challenge. The first mistake many of us make is including the modal within the loop. To prevent the duplication of the modal we need to make it fully dynamically. I have included a full example without having to duplicate the modal inside of the loop. I hope that helps
here is a full example
import React, { Component } from 'react';
import { Button, Alert, Input, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
class History extends Component
{
constructor(props)
{
super(props);
this.state = {
userHistory: [{'id': 1, 'test': 'this is a test'}, {'id': 2, 'test': 'this is a test2'}, {'id': 3, 'test': 'this is a test3'}],
showLog: false,
logID: null
}
}
render()
{
const history = this.state.userHistory.map( (ticket, key) =>
{
return (
<tr key={key}>
<td>{ticket.test}</td>
<td>{ticket.id ? <Button color="info" onClick={() => this.setState({logID: ticket.id, showLog: true})}>View</Button> : ''}</td>
</tr>
)
});
return (
<div className="card-body">
<table class="table table-striped">
<thead>
<tr>
<th>test</th>
<th>modal</th>
</tr>
</thead>
<tbody>
{history}
</tbody>
</table>
<Modal id={this.state.logID} isOpen={this.state.showLog} fade="false" toggle={() => this.setState({showLog: false})}>
<ModalHeader toggle={() => this.setState({showLog: false})}>@jerryurenaa is awesome :D</ModalHeader>
<ModalBody>
<p>Modal Number: {this.state.logID}</p>
</ModalBody>
<ModalFooter>
<Button onClick={() => this.setState({showLog: false})}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
}
export default History;
本文标签: javascriptReactJS Modal opening multiple times when in a LoopStack Overflow
版权声明:本文标题:javascript - ReactJS Modal opening multiple times when in a Loop - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742327635a2454044.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论