I have a addCounter button and each time the button is clicked, a div element is created with a pair of increment and decrement button into the dom. Now how do I pass unique id into each of the buttons so that I could manage states in every div element with redux? This is what I have tried...
const INCREMENT = 'increment';
const DECREMENT = 'decrement';
const ADDCOUNTER = 'addCounter';
const initialCounterState = [
{
id: 0,
value: 0
},
];
const addCounterDiv = () => {
const newContent = `
<div class="max-w-md mx-auto mt-10 space-y-5">
<div
class="p-4 h-auto flex flex-col items-center justify-center space-y-5 bg-white rounded shadow"
>
<div class="counter text-2xl font-semibold"> 0</div>
<div class="flex space-x-3">
<button
class="increment bg-indigo-400 text-white px-3 py-2 rounded shadow"
>
Increment
</button>
<button
class="decrement bg-red-400 text-white px-3 py-2 rounded shadow"
>
Decrement
</button>
</div>
</div>
</div>
`;
var newDiv = document.createElement("div");
newDiv.innerHTML = newContent;
// add the newly created element and its content into the DOM
var mainDiv = document.getElementById("mainDiv");
mainDiv.appendChild(newDiv);
};
// create action creators
const addCounterAction = () => {
return {
type: ADDCOUNTER,
}
};
const incrementAction = (id, value) => {
return {
type: INCREMENT,
payload: {
id: parseInt(id),
value: value
}
}
};
const decrementAction = (id, value) => {
return {
type: DECREMENT,
payload: {
id: parseInt(id),
value: value
}
}
};
// create reducers
function counterReducer(state = initialCounterState, action){
if(action.type === ADDCOUNTER){
const newItem =
{
id: state.length,
value: 0
};
const updatedState = [...state, newItem];
return updatedState;
}else if(action.type === INCREMENT){
const copiedState = state.map((object)=>({
...object,
}));
const index = copiedState.findIndex((el)=>el.id === action.payload.id);
if(index > -1){
copiedState[index].value = copiedState[index].value + action.payload.value;
return copiedState;
}
return copiedState;
}else if(action.type === DECREMENT){
const copiedState = state.map((object)=>({
...object,
}));
const index = copiedState.findIndex((el)=>el.id === action.payload.id);
if(index > -1){
copiedState[index].value = copiedState[index].value - action.payload.value;
return copiedState;
}
return copiedState;
}else{
return state;
}
};
// create store
const store = Redux.createStore(counterReducer);
// Show in UI
const renderContainer = () => {
const state = store.getState();
const counterNodeList = document.querySelectorAll('.counter');
for (let index = 0; index < counterNodeList.length; index++) {
const element = counterNodeList[index];
element.innerText = state[index].value;
}
console.log(store.getState());
};
//renderContainer();
store.subscribe(renderContainer);
// event listener
const addCounterEl = document.getElementById('addCounter');
addCounterEl.addEventListener('click', ()=>{
store.dispatch(addCounterAction());
addCounterDiv();
// renderContainer();
})
document.querySelectorAll('.increment').forEach((value)=>{
value.setAttribute('id', Math.random().toString(16).slice(2));
})
document.querySelectorAll('.increment').forEach((value, index)=>{
value.addEventListener('click', (e)=>{
store.dispatch(incrementAction(e.target.id, 1))
})
})
const decrementNodeList = document.querySelectorAll('.decrement');
for (let index = 0; index < decrementNodeList.length; index++) {
decrementNodeList[index].addEventListener('click', (e)=>{
decrementNodeList[index].setAttribute('id', index);
store.dispatch(decrementAction(e.target.id, 1));
})
};
console.log(store.getState())
And the html looks like this...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Simple Counter Application</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/redux@4.2.0/dist/redux.min.js"></script>
</head>
<body>
<div id="mainDiv" class="w-screen h-screen p-10 bg-gray-100 text-slate-700">
<!-- header -->
<h1 class="max-w-md mx-auto text-center text-2xl font-bold">
Simple Counter Application
</h1>
<!-- counters -->
<div class="max-w-md mx-auto mt-10 space-y-5">
<div
class="p-4 h-auto flex flex-col items-center justify-center space-y-5 bg-white rounded shadow"
>
<div class="counter text-2xl font-semibold">0</div>
<div class="flex space-x-3">
<button
class="increment bg-indigo-400 text-white px-3 py-2 rounded shadow"
>
Increment
</button>
<button
class="decrement bg-red-400 text-white px-3 py-2 rounded shadow"
>
Decrement
</button>
</div>
</div>
</div>
<div class="mt-6 flex flex-row space-x-4 justify-end">
<button
class="bg-indigo-400 text-white px-3 py-2 rounded shadow"
id="addCounter"
>
+ Add Counter
</button>
<button
class="bg-red-400 text-white px-3 py-2 rounded shadow"
id="reset"
>
Reset
</button>
</div>
</div>
<script src="./script.js"></script>
</body>
</html>