Previously I wrote a Pomodoro timer app. The code is contained in a single React component. This is generally bad practice - we want components to each be responsible for a single bit of functionality and be reusable, so we will we split out functionality into smaller components.
First I made a folder called "components", which will house the sub components and their styles.
There are 3 elements we can immediately split out:
- The main timer and button ("Tomato" element)
- The Break length controls
- The Session length controls
Break Length
This section has a breakLength
value contained in the state and two button handler methods to increase/decrease this value.
First, we create a new component called BreakLength
and paste the JSX into the render method. As we are now in a child component, and React has unidirectional data flow, we cannot update the breakLength
value in the parent component from the BreakLength
component.
Therefore, we pass a reference to the method into the BreakLength
component as a property and call this in a new onClick
handler. This will call the parent method and update its state.
The breakLength
value is passed to the new component as a child property. When the state is changed in the parent, this will change the property value and re-render the BreakLength
component.
Session Length
This is refactored in the same way:
Tomato
The Tomato has 2 functions - handleStartStop
and handleReset
. Again, we pass references to these as properties and call them in the onClick
handlers in the child Tomato component. The minutes and second properties are passed as props to the Tomato component.
Now our main component is much smaller and we have a better separation of concerns. We can also extract some of the styles in Session.css
that only apply to the Tomato into a new CSS file and include it just in this component.
Top comments (1)
I wonder if you could reduce the
BreakLength
andSessionLength
components down into a single component as well. They seem to perform similar actions. Maybe the text in theh2
tag and thehandle*Decrement
/handle*Increment
functions can all be passed in as props.Do you have this hosted anywhere?