Skip to content

Instantly share code, notes, and snippets.

@shuantsu-zz
Last active April 27, 2021 17:50
Show Gist options
  • Save shuantsu-zz/7300a80d0b57c595e97f48e25044da78 to your computer and use it in GitHub Desktop.
Save shuantsu-zz/7300a80d0b57c595e97f48e25044da78 to your computer and use it in GitHub Desktop.
React Counters
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: roboto, sans-serif;
padding: 20px;
color: rgb(101, 103, 114);
}
button {
display: inline-block;
border: 0;
padding: 8px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
opacity: .6;
}
.counter {
padding: 10px;
display: flex;
justify-content: space-between;
max-width: 500px;
align-items: center;
}
.green {
color: green;
}
.red {
color: red;
}
.remove {
background: red;
color: white;
}
.flex-between {
display: flex;
justify-content: space-between;
flex: 1;
align-items: center;
}
.mx-20{
margin: 0 20px;
}
import {React, useEffect, useState} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
const Counter = ({onIncrement, onDecrement, value, label, onRemove, id}) => {
return <>
<button onClick={onDecrement}>-</button>
<div className="flex-between mx-20">
<span>{label}: <strong className={value >= 0 ? "green" : "red"}>{value}</strong></span>
<button onClick={onIncrement}>+</button>
</div>
<button onClick={()=>onRemove(id)} className="remove">X</button>
</>
};
const App = () => {
const [ newItem, setNewItem ] = useState("");
const [ counters, setCounters ] = useState([]);
useEffect(()=>{
const c = localStorage.getItem('counters');
if (c) setCounters(JSON.parse(c));
const i = localStorage.getItem('newItem');
if (i) setNewItem(JSON.parse(i));
}, []);
useEffect(()=>{
localStorage.setItem('counters', JSON.stringify(counters));
}, [counters]);
useEffect(()=>{
localStorage.setItem('newItem', JSON.stringify(newItem));
}, [newItem]);
const submit = e => {
if (e.key === "Enter") {
if (newItem.trim().length === 0) return false;
setCounters([...counters, {count:0, label:newItem}]);
setNewItem('');
}
};
const addValue = (key, n) => {
let arrCopy = [...counters];
arrCopy[key] = {count: counters[key].count + n, label: counters[key].label};
setCounters(arrCopy);
};
const onIncrement = key => addValue(key, 1);
const onDecrement = key => addValue(key, -1);
const onRemove = key => {
const copy = [...counters];
copy.splice(key, 1);
setCounters(copy);
};
const getTotal = () => counters.reduce((acc, item) => acc + item.count, 0);
return <>
<h1>counters. counters everywhere.</h1>
{counters.length !== 0 ? counters.map((counter, key)=>{
return (
<div className="counter" key={key}>
<Counter
key={key}
id={key}
onRemove={onRemove}
onIncrement={()=>onIncrement(key)}
onDecrement={()=>onDecrement(key)}
value={counter.count}
label={counter.label}
/>
</div>
)
}) : <><br/><span className="msg">Nothing to see here...</span><br/></>
}
<br/>
<input
placeholder="new item"
type="text"
onKeyDown={e=>submit(e)}
value={newItem}
onChange={e => setNewItem(e.target.value)}
/>
<br/>
<br/>
<h1>total: <span className={getTotal() >= 0 ? "green" : "red"}>{getTotal()}</span></h1>
</>
};
ReactDOM.render(
<App />,
document.getElementById('root')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment