Reputation: 1195
At the moment the code does what I want it to do but it also crashes my application. I think it's because of an endless loop but I am not sure. I want the code to check the two variables, if one equals the other, I want to change the state of the modal.
newTimestamp gets renewed every second based upon the seconds passed in ReactPlayer.
How can I prevent an endless loop in this situation?
This is my code:
import React, { Component } from 'react';
import { Modal, Button, Tooltip, Link, ControlLabel } from 'react-bootstrap';
export class CommentsModalAdmin extends Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
};
this.close = this.close.bind(this);
this.open = this.open.bind(this);
}
componentWillReceiveProps(props){
const newTimestamp = this.props.newTimestamp;
const timestamp = this.props.comment.timestamp;
if (newTimestamp === timestamp ){
this.setState({ showModal: true });
this.props.stopVideo();
}
}
close() {
this.setState({ showModal: false });
this.props.playVideo();
}
open() {
this.setState({ showModal: true });
this.props.stopVideo();
}
render() {
const { newTimestamp, city, person, location, title, content, fileLink, timestamp } = this.props.comment;
return (
<div className="flex">
<a onClick={this.open}><span className="modal-bg"><span style={{ height: rand }} className="modal-color" ></span></span></a>
<Modal show={this.state.showModal} onHide={this.close} bsSize="lg">
<Modal.Header closeButton>
<Modal.Title >{title}</Modal.Title>
</Modal.Header>
<Modal.Body>
<p><ControlLabel>Tagged city: </ControlLabel> {city}</p>
<p><ControlLabel>Tagged person: </ControlLabel> {person}</p>
<p><ControlLabel>Tagged location: </ControlLabel> {location}</p>
<p><ControlLabel>Tagged image: </ControlLabel></p>
<img src={fileLink} width="100%"/>
<ControlLabel>Tagged content: </ControlLabel> <div dangerouslySetInnerHTML={{__html: content}} />
</Modal.Body>
<Modal.Footer>
<Button onClick={this.close}>Close</Button>
</Modal.Footer>
</Modal>
</div>
);
}
}
These are the error messages I see: "Uncaught RangeError: Maximum call stack size exceeded"
And
"Warning: performUpdateIfNecessary: Unexpected batch number (current 3200, pending 1783"
I found that adding this.props.stopVideo(); caused the loop but I don't understand why. Anyone able to explain?
Upvotes: 1
Views: 909
Reputation: 1195
I managed to solve this by adding an extra if/else condition like this:
componentWillReceiveProps(nextProps){
const newTimestamp = this.props.newTimestamp;
const timestamp = this.props.comment.timestamp;
if(nextProps !== this.props){
if(this.state.showModal === false){
if (newTimestamp === timestamp ){
this.setState({ showModal: true });
this.props.stopVideo();
}
}
}
}
Hope it can help anyone with a simular problem.
Upvotes: 0
Reputation: 18546
You're using the componentWillReceiveProps
method. This method is executed every time the component receives new (or any) props. Inside that method you trigger a function that gets called in the parent of the component, which in return, triggers another function that utilizes setState
.
componentWillReceiveProps(props) {
// ...
this.props.stopVideo();
}
setState
causes a re-render, and therefore also the CommentsModalAdmin
is re-rendered and componentWillReceiveProps
is called. This results in the loop.
You might want to revise that method (or check if the props actually changed with something like props == this.props
).
Upvotes: 3