Ad
Getting This.startBreak() Is Not A Function Error In React.js
I'm a newbie working on a pomodoro timer app in react and I'm getting this error after calling a function within setInterval():
TypeError: this.startBreak is not a function
Surely it's something trivial so I'll be grateful for any advice. Here's the code:
startSession = () => {
let sessionSecondsTotal = (this.state.hours * 60 * 60) + (this.state.minutes * 60) + (this.state.seconds);
let hoursNode = document.getElementById("hours");
let minutesNode = document.getElementById("minutes");
let secondsNode = document.getElementById("seconds");
let hoursShow = this.state.hours;
let minutesShow = this.state.minutes;
let secondsShow = this.state.seconds;
setInterval(function(){
secondsShow = secondsShow - 1;
if(secondsShow <= 0){
secondsShow = 59;
minutesShow = minutesShow - 1;
}else if(hoursShow > 0){
if(minutesShow <= 0){
hoursShow = hoursShow - 1;
minutesShow = 59;
}
}
hoursNode.textContent = hoursShow.toString();
minutesNode.textContent = minutesShow.toString();
secondsNode.textContent = secondsShow.toString();
sessionSecondsTotal = sessionSecondsTotal - 1;
if(sessionSecondsTotal === 0){
this.startBreak();
}
},1000)
}
Ad
Answer
When you define a function(){}
in javascript a new context (this
) will be created.
You can read more about contexts here
There are many ways to handle it:
1) Save your previous context to variable and use it inside new function
let hoursShow = this.state.hours;
let minutesShow = this.state.minutes;
let secondsShow = this.state.seconds;
const self = this;
setInterval(function(){
secondsShow = secondsShow - 1;
if(secondsShow <= 0){
secondsShow = 59;
minutesShow = minutesShow - 1;
}else if(hoursShow > 0){
if(minutesShow <= 0){
hoursShow = hoursShow - 1;
minutesShow = 59;
}
}
hoursNode.textContent = hoursShow.toString();
minutesNode.textContent = minutesShow.toString();
secondsNode.textContent = secondsShow.toString();
sessionSecondsTotal = sessionSecondsTotal - 1;
if(sessionSecondsTotal === 0){
self.startBreak();
}
},1000)
}
2) Use arrow function, because it will use context from upper scope
let hoursShow = this.state.hours;
let minutesShow = this.state.minutes;
let secondsShow = this.state.seconds;
setInterval(() => {
secondsShow = secondsShow - 1;
if(secondsShow <= 0){
secondsShow = 59;
minutesShow = minutesShow - 1;
}else if(hoursShow > 0){
if(minutesShow <= 0){
hoursShow = hoursShow - 1;
minutesShow = 59;
}
}
hoursNode.textContent = hoursShow.toString();
minutesNode.textContent = minutesShow.toString();
secondsNode.textContent = secondsShow.toString();
sessionSecondsTotal = sessionSecondsTotal - 1;
if(sessionSecondsTotal === 0){
this.startBreak();
}
},1000)
}
3) Bind context to the new function
let hoursShow = this.state.hours;
let minutesShow = this.state.minutes;
let secondsShow = this.state.seconds;
setInterval((function(){
secondsShow = secondsShow - 1;
if(secondsShow <= 0){
secondsShow = 59;
minutesShow = minutesShow - 1;
}else if(hoursShow > 0){
if(minutesShow <= 0){
hoursShow = hoursShow - 1;
minutesShow = 59;
}
}
hoursNode.textContent = hoursShow.toString();
minutesNode.textContent = minutesShow.toString();
secondsNode.textContent = secondsShow.toString();
sessionSecondsTotal = sessionSecondsTotal - 1;
if(sessionSecondsTotal === 0){
this.startBreak();
}
}).bind(this),1000)
}
Ad
source: stackoverflow.com
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
Ad