Here is my code:
// index.tsx
<button id="start_stop" onClick={() => dispatch(toggleSwitch({ dispatch }))}>
{active ? "Pause" : "Start"}
</button>
// timerSlice.ts
// ...
const timerSlice = createSlice({
name: "timer",
initialState,
reducers: {
toggleSwitch: (state, action) => {
const { dispatch } = action.payload;
if (state.intervalId) {
clearInterval(state.intervalId);
return {
...state,
intervalId: null,
active: false,
};
} else {
// I NEED HELP WITH THIS PART
const intervalId = setInterval(() => {
if (state.timer === 0) {
const audio = document.getElementById("beep") as HTMLAudioElement;
playAudio(audio);
// 1. How to call to sibling reducer function
// 2. Is it correct to use dispatch
dispatch(timerSlice.actions.toggleStatus());
dispatch(timerSlice.actions.recalculateTimer());
return;
}
dispatch(timerSlice.actions.decreaseTimer());
}, 1000);
return {
...state,
active: true,
intervalId,
};
}
},
decreaseBreak: (state, action) => {
const { dispatch } = action.payload;
if (state.active || state.break <= 1) return;
state.break = state.break - 1;
if (state.status === "BREAK") {
// 3. How can I call a common-use reducer from another, like nested functions
dispatch(timerSlice.actions.recalculateTimer());
}
},
// ...
}
});
This code gives me the following error on the console: Uncaught Error: You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.
I tried not to call a reducer from the other as possible, but it had a lot of repeated code and the worst, I should call to another reducer func inside the setInterval callback func anyway. then I tried to convert common-use reducer functions to pure functions:
const toggleStatus = (state: ITimer): ITimer => {
return {
...state,
status: state.status === "SESSION" ? "BREAK" : "SESSION",
};
};
const recalculateTimer = (state: ITimer): ITimer => {
return {
...state,
timer: state[state.status.toLowerCase() as "session" | "break"] * 60,
};
};
toggleSwitch: (state) => {
if (state.intervalId) {
// ...
} else {
const intervalId = setInterval(() => {
if (state.timer === 0) {
const audio = document.getElementById("beep") as HTMLAudioElement;
playAudio(audio);
// HERE IS THE NEW CODE
const toggledStatusState = toggleStatus(state);
const recalculatedTimerState = recalculateTimer(toggledStatusState);
return recalculatedTimerState;
}
state.timer = state.timer - 1;
}, 1000);
return {
...state,
active: true,
intervalId,
};
}
},
this also gives me an Error: **Uncaught TypeError: Cannot perform 'get' on a proxy that has been revoked **