Hey! I'm on a mission to make 100 React.js projects ending May 31st. Please follow my dev.to profile or my twitter for updates and feel free to reach out if you have questions. Thanks for your support!
Link to today's deployed app: Link
Link to the repo: github
So I'm a big fan of the Pomodoro method. I think there are some times when it works well and others when it doesn't, but overall it's a great way to parcel out your time and to make sure you have those necessary breaks throughout your time at work.
Today I wanted to use React Redux to store the counter state in a Redux store using the react-redux
npm package.
Redux is built using the Context API under the hood so the first step is wrapping your application in the React Redux {Provider} component at the root level.
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'
import store from './redux'
import './index.css';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
The next step is to write your actions and reducer, and to create a store for Redux in a separate Javascript file.
import {createStore} from 'redux'
export function decrement() {
return {
type: "DECREMENT"
}
}
export function resetCount() {
return {
type: "RESET"
}
}
export function reducer(count, action) {
switch (action.type) {
case ("DECREMENT"):
return count - 1
case ("RESET"):
return 1500
default:
return 1500
}
}
const store = createStore(reducer);
export default store;
The next step is to actually write out your React components, and import the connect() method from react-redux
into the React component that will be using it.
import React,{useState,useEffect} from 'react'
import {connect} from 'react-redux'
import {decrement,resetCount} from '../redux'
import tomatoImage from '../images/tomato.png'
function Pomodoro(props) {
const [isCounting,setIsCounting] = useState(false)
const [hasCounted,setHasCounted] = useState(false)
const [minutes,setMinutes] = useState(0)
const [seconds,setSeconds] = useState(0)
const [buttonClass,setButtonClass] = useState("play")
useEffect(() => {
setTimeState()
if (props.count > 0 && isCounting) {
// is counting and there's time left
setTimeout(() => {
props.decrement()
},1000)
} else if (props.count > 0 && isCounting) {
// time has run out
setIsCounting(false)
setHasCounted(true)
setButtonClass("play")
props.resetCount()
}
},[props.count,isCounting])
function setTimeState() {
const minsRaw = Math.floor(props.count / 60);
const secsRaw = props.count - (minsRaw * 60)
const minsString = minsRaw.toString()
const secsString = secsRaw.toString()
const minsFinal = minsString.length < 2 ? "0"+minsString : minsString
const secsFinal = secsString.length < 2 ? "0"+secsString : secsString
setMinutes(minsFinal)
setSeconds(secsFinal)
}
function handleClick() {
// play & has not counted before
if (!isCounting) {
setIsCounting(true)
setButtonClass("pause")
}
// pause
else {
setIsCounting(false)
setButtonClass("play")
}
}
return (
...
// excluding JSX here because you probably know what
// Pomodoro html elements look like
)
}
function mapStateToProps(state) {
return {
count: state
}
}
const mapDispatchToProps = {
decrement: decrement,
resetCount: resetCount
}
export default connect(mapStateToProps, mapDispatchToProps)(Pomodoro)
If you like projects like this and want to stay up to date with more, check out my Twitter @jwhubert91, I follow back! See you tomorrow for another project.
Top comments (1)
If continuously button is clicked the timer will move fast.