如何使用VanillaJS和Redux制作多计数器应用程序



这是我的代码。我想用香草js和redux制作多个计数器应用程序。但是当我点击";添加";字段,它只是更改我的主计数器值,而不是自己创建一个新的计数器。但我希望它在点击";添加";按钮例如,检查链接。

想要制作真正的相同

我的代码中有什么需要更改的?

//select dom element
let counterCountainer = document.getElementById("counter-container");
const addBtn = document.getElementById("add");
// create initial state
let initialState = [
{
id: 1,
value: 0,
},
];
// create variable fro unique id
let id = 1;
// action identifiers
const INCREMENT = "increment";
const DECREMENT = "decrement";
const ADD = "add";
// create reducer function
function counterReducer(state = initialState, action) {
if (action.type === ADD) {
const copyState = [...state];
copyState.push({
id: ++id,
value: id - 1,
});
return copyState;
} else if (action.type === INCREMENT) {
const copyState = [...state];
console.log(copyState);
console.log(action);
const index = copyState.findIndex(
(item) => item.id === action.payload.id
);
copyState[index].value += action.payload.value;
console.log(copyState);
return copyState;
} else if (action.type === DECREMENT) {
const copyState = [...state];
const index = copyState.findIndex(
(item) => item.id === action.payload.id
);
copyState[index].value -= action.payload.value;
return copyState;
} else {
return state;
}
}
// create store
const store = Redux.createStore(counterReducer, initialState);
// action creators
const increment = (id, value) => {
return {
type: INCREMENT,
payload: {
value: value,
id: id,
},
};
};
const decrement = (id, value) => {
return {
type: DECREMENT,
payload: {
value: value,
id: id,
},
};
};
// create new counter div when click add counter button
addBtn.addEventListener("click", function () {
store.dispatch({
type: "add",
});
});
// create render function for show updated state in ui
function render() {
const state = store.getState();
state.forEach((item) => {
const div = document.createElement("div");
div.classList =
"p-4 h-auto flex flex-col items-center justify-center space-y-5 bg-white rounded shadow counter";
const counter = document.createElement("div");
counter.classList = "text-2xl font-semibold";
div.appendChild(counter);
counter.innerText = item.value;
const btnContainer = document.createElement("div");
btnContainer.classList = "flex space-x-3";
const incrementBtn = document.createElement("button");
incrementBtn.classList =
"bg-indigo-400 text-white px-3 py-2 rounded shadow";
incrementBtn.innerText = "Increment";
incrementBtn.onclick = function () {
store.dispatch(increment(item.id, item.id));
};
const decrementBtn = document.createElement("button");
decrementBtn.classList =
"bg-red-400 text-white px-3 py-2 rounded shadow";
decrementBtn.innerText = "Decrement";
decrementBtn.onclick = function () {
store.dispatch(decrement(item.id, item.id));
};
btnContainer.appendChild(incrementBtn);
btnContainer.appendChild(decrementBtn);
div.appendChild(btnContainer);
counterCountainer.innerHTML = "";
counterCountainer.append(div);
});
}
// update ui initially
render();
// subscribe store
store.subscribe(render);
<!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>
<!-- import redux from cdn -->
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
</head>
<body>
<div class="w-screen min-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 Multi Counter Application
</h1>
<!-- counters -->
<div class="mx-auto max-w-md mt-10 space-y-5" id="counter-container"></div>
<div class="mt-10 mx-auto max-w-md text-center">
<button id="add" class="bg-indigo-400 text-white px-3 py-2 rounded shadow">
Add Counter
</button>
<button id="reset" class="bg-red-400 text-white px-3 py-2 rounded shadow">
Reset
</button>
</div>
</div>
<script src="index.js"></script>
</body>
</html>

使用RTK管理实体的最佳方法是使用createEntityAdapterutils

interface Counter {
id: string
value: number
}
const counterAdapter = createEntityAdapter<Counter>({
selectId: (counter) => counter.id,
sortComparer: (a, b) => a.value.localeCompare(b.value),
})
export const {
selectById: selectCounterById,
} = usersAdapter.getSelectors()
const counterSlice = createSlice({
name: 'counter',
initialState: counterAdapter.getInitialState(),
reducers: {
increment(state, action: PayloadAction<{ id: string }>) {
const counter = selectCounterById(state, action.payload.id);
counter.value = counter.value + 1;
counterAdapter.upsertOne(state, counter);
},
},
})

相关内容

最新更新