In this lesson we'll build a stopwatch component that maintains its own state. We'll start by creating the static UI, then take the dynamic parts and accept them as props. After that we'll refactor that to state and add event handlers to update the state.
Hi Kent, awesome course. I'm new to both JS and React. Just wanting to check with you that in the "Use Component State with React" lecture, the "startTime" variable is just a placeholder variable changes in value all the time? Ie, it does not record the actual start time of when I click the start button and later when I click the stop button, the start time has actually "moved". Thanks, Adam
Hi! So if you look closely at the logic, we set the start time once you click the start button and then reference that in the setInterval call. So it's set once each time you click start and never changes.
Hi! So this the code that i have written for the above practical
class StopWatch extends React.Component{ state = {lapse: 0, isRunning: false}
handleStartClick(){ this.setState({lapse: 10, isRunning: true})
} handleClearClick(){
}
render(){ const {lapse, isRunning} = this.state; return ( <div> <label>{lapse}ms</label> <button onClick={this.handleStartClick}>{isRunning ? 'Stop' : 'Start'}</button> <button onClick={this.handleClearClick}>Clear</button> </div> ) } }
ReactDOM.render(<StopWatch />,document.getElementById('root'))
getting this error on clicking 'start' button
Uncaught TypeError: Cannot read property 'setState' of undefined
and the error is completeley expected because wrong referencing of 'this'
but hows your prac working?
Change your implementation to this:
class StopWatch extends React.Component{
state = {lapse: 0, isRunning: false}
handleStartClick = () => {
this.setState({lapse: 10, isRunning: true})
}
handleClearClick = () => {
}
render(){
const {lapse, isRunning} = this.state;
return (
<div>
<label>{lapse}ms</label>
<button onClick={this.handleStartClick}>{isRunning ? 'Stop' : 'Start'}</button>
<button onClick={this.handleClearClick}>Clear</button>
</div>
)
}
}
ReactDOM.render(<StopWatch />,document.getElementById('root'))
See this video for an explanation about why.
Good luck!
This example code behaves weirdly when run in Firefox on my box. To fix it, I had to pass in a delay parameter to the call to setInterval like so:
this.timer = setInterval(() => {
this.setState({
lapse: Date.now() - startTime,})
}, 100)
I ran into the same problem as Cornelius on Firefox. It looks like Firefox doesn't work correctly if you don't provide a delay to setInterval. I just explicitly set it to 0 and it fixed the problem.
Hi Kent, thank you for this series of videos. I am trying to implement it in a React project, but it doesn't work. It says syntaxError: Unexpected token =
I am compiling with webpack and babel-loader Thank you
Hi mattia,
The public class fields syntax (state = {}
) is currently a stage-3 proposal in the EcmaScript standardization process of the TC39. This means that it wouldn't be included if you're using babel-preset-env
and you'll need to include the babel-plugin-transform-class-properties
transform for it in your babel configuration. If you're using create-react-app, it's included by default.
Learn more about the feature from this lesson.
Thanks for the course. Another question about the public class fields. Instead of
handleClearClick = () => {
You could have done this:
handleRunClick() {...}...
The public class field will create a new instance of the methods with each class instantiation, whereas the regular class method is the same thing for each class instance.
The regular class methods would require you to bind the handleRunClick and handleClearClick to this.
Why did you use the public class fields and what do you think are the benefits over the regular class methods?
Wow! You totally explained it in a way that couldn't have been more helpful in lesson 12.
https://egghead.io/lessons/egghead-use-class-components-with-react
PS: Looking back at this discussion, I now see you already mentioned that.
Yeah, the order of these particular lessons was a little tricky 😅
What IDE are you using? I noticed yours has intellisense.
I'm using atom
Hi Kent,
I know this is a bit off-topic but can you explain how this.timer
in handleClearClick
is able to reference the timer from handleRunClick
?
Thanks! Melissa.
this
represents the object which is our instance of the stopwatch component. All the methods there have access to that object and the properties on it. So when handleRunClick
sets this.timer
, because handleClearClick
has access to the same this
object it can access this.timer
:)
Hello Kent, What are you using to make the browser dynamically reflect changes as you type - considering we're updating a plain '.html' file, and don't have a build system like webpack running. Thanks.