<h1>Vanilla JS Redux example</h1>
<div class="container">
<button id="increaseCounterButton"> + (0) </button>
<span id="countLabel"></span>
<button id="decreaseCounterButton"> - (0) </button>
</div>
h1{
text-align: center;
}
.container{
display:flex;
width:100%;
justify-content: center;
align-items:center;
}
#countLabel{
margin: 40px;
font-size: 2rem;
}
button{
display: inline-block;
width: 80px;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border: 1px solid transparent;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: .25rem;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
/****** the example starts here ******/
//actions
const INCREASE_COUNTER = 'INCREASE_COUNTER';
const DECREASE_COUNTER = 'DECREASE_COUNTER';
function increaseCounter(amount){
return {
type: INCREASE_COUNTER,
payload: amount
}
}
function decreaseCounter(amount){
return {
type: DECREASE_COUNTER,
payload: amount
}
}
//reducers
function counterReducer(state={count:0, increaseClicks:0, decreaseClicks:0}, action){
switch(action.type){
case INCREASE_COUNTER:
return {
...state,
count: state.count + action.payload,
increaseClicks: state.increaseClicks + 1
};
case DECREASE_COUNTER:
return {
...state,
count: state.count - action.payload,
decreaseClicks: state.decreaseClicks + 1
};
default:
return state;
}
}
//codepen equivalent to import { createStore } from 'redux'
const { createStore } = Redux;
//declare store
let store = createStore(counterReducer);
//reference UI elements
const increaseCounterButton = document.getElementById('increaseCounterButton');
const decreaseCounterButton = document.getElementById('decreaseCounterButton');
const countLabel = document.getElementById('countLabel');
//dispatch actions on buttons click
increaseCounterButton.addEventListener('click', ()=>{
store.dispatch(increaseCounter(1));
});
decreaseCounterButton.addEventListener('click', ()=>{
store.dispatch(decreaseCounter(1));
});
//render cycle that gets called every time the store is modified
const render = () => {
//get current state
const state = store.getState();
//update UI based on current state
countLabel.innerHTML = state.count;
increaseCounterButton.innerHTML = `+ (${state.increaseClicks})`;
decreaseCounterButton.innerHTML = `+ (${state.decreaseClicks})`;
}
render();
store.subscribe(render);
View Compiled
This Pen doesn't use any external CSS resources.