A counter using useEffect and useReducer
0
import React, { useReducer, useEffect } from "react";
function IntervalCounter() {
const [state, dispatch] = useReducer(reducer, initialState);
const { count, step } = state;
useEffect(() => {
const id = setInterval(() => {
dispatch({ type: 'tick' });
}, 1000);
return () => clearInterval(id);
}, [dispatch]);
return (
<>
<h1>{count}</h1>
<label htmlFor="stepInput">Amount to add each second:</label>
<input id="stepInput" value={step} onChange={e => {
dispatch({
type: 'step',
step: Number(e.target.value)
});
}} />
</>
);
}
const initialState = {
count: 0,
step: 1,
};
function reducer(state, action) {
const { count, step } = state;
if (action.type === 'tick') {
return { count: count + step, step };
} else if (action.type === 'step') {
return { count, step: action.step };
} else {
throw new Error();
}
}
export default IntervalCounter;
Counter that randomly changes color on change:
0
import React, { useState, useEffect} from "react";
function IntervalCounterColor() {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
const [color, setColor] = useState('white');
const colors = ['blue', 'red', 'green','yellow','purple','pink','aqua'];
useEffect(() => {
const id = setInterval(() => {
setCount(c => c + step);
setColor(colors[Math.floor(Math.random() * 7)]);
}, 1000);
return () => clearInterval(id);
}, [step]);
return (
<>
<h1><span style={{background: color, padding:'.25em .5em'}}>{count}</span></h1>
<label for="countInput">Amount to add each second:</label>
<input id="countInput" value={step} onChange={e => setStep(Number(e.target.value))} />
</>
);
}
export default IntervalCounterColor;
From: overreacted.io blog
I'm adding to two counts, but only one makes me change colour: a=0 and b=0
import React, {useEffect, useState} from 'react'
function PropChangeWatch({ a, b }) {
const [color, setColor] = useState('white');
const colors = ['lightblue', 'red', 'lightgreen','yellow','lavender','pink','aqua'];
useEffect(() => {
console.log("value of 'a' changed to", a);
setColor(colors[Math.floor(Math.random() * 7)]);
}, [a]);
return (
<div style={{backgroundColor: color}}>
I'm adding to two counts, but only one makes me change colour: a={a} and b={b}
</div>
);
}
function PropsUpdate() {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
return (
<div>
<PropChangeWatch a={count1} b={count2} />
<button onClick={() => setCount1(count1 + 1)}>Add 1 to the value of a</button>
<button onClick={() => setCount2(count2 + 1)}>Add 1 to the value of b</button>
</div>
);
}
export default PropsUpdate;
From an example on Dave Ceddia's Blog
App that calculates factors of a number, and can also toggle theme
useEffect with useCallback to prevent re-rendering of list when only Theme (dark mode) changes:
0Count of useEffect Triggers (ie list of factors re-calculated and re-rendered)
useEffect without memoization to prevent re-rendering of list when only Theme (dark mode) changes:
0Count of useEffect Triggers (ie list of factors re-calculated and re-rendered)
From Vaishnav's Blog