Reputation: 3434
So I just started implementing Redux in my application and so far so good, but now I got to a state variable that has some side effects (? im guessing) within its setState function and I can't figure out how to implement that with redux. I have an idea, but doesn't seem to be the best option.
function App() {
const [paused, setPaused] = useState(false);
const handlePause = () => {
setPaused(oldPauseStatus => {
!oldPauseStatus ? pauseVisualizationHandler() : resumeVisualizationHandler();
return !oldPauseStatus;
})
}
const pauseVisualizationhandler = () => {...somecode...};
const resumeVisualizationhandler = () => {...somecode...};
return (<button id={"pausehandler"} onClick={handlePause}>
{paused ? `RESUME` : `PAUSE`}
</button>)
}
Now the problem is obvious, it is the pause
and resume
handlers within the setPaused
.
For action I have:
const setPaused = (paused) => {
return paused
? {
type: PAUSE,
payload: { paused },
}
: {
type: RESUME,
payload: { paused },
};
};
And for reducer:
const initialState = {
started: false,
paused: false,
};
const animationStateReducer = (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
case PAUSE:
return {
...state,
paused: payload.paused,
};
case RESUME:
return {
...state,
paused: payload.paused,
};
default:
return state;
}
};
And the whole thing implemented with Redux:
import { setPaused } from "./actions"
function App() {
const { paused } = useSelector(state=>state.animationState);
useEffect(() => {
paused ? pauseVisualizationHandler() :
resumeVisualizationHandler();
}, [paused])
const handlePause = () => {
setPaused(!paused)
}
const pauseVisualizationhandler = () => {...somecode...};
const resumeVisualizationhandler = () => {...somecode...};
return (<button id={"pausehandler"} onClick={handlePause}>
{paused ? `RESUME` : `PAUSE`}
</button>)
}
Now this is working just fine when I dispatch(setPaused(trueOrFalse))
, however, I can't figure out where to put my visualizationHandlers
now? The only thing that comes to mind is to use useEffect
that will track when paused
is changed, and do it there, but if I have multiple such states, wouldnt that pollute my component with lots of useEffects
...? (And I do have 1 that is a bit more complex than this). What would be the correct approach here and is useEffect
my only viable option?
Upvotes: 0
Views: 81
Reputation: 6582
I think what you're trying to do is this:
function App() {
const [paused, setPaused] = useState(false);
const handlePause = () => {
setPaused((oldPauseStatus) => !oldPauseStatus);
};
useEffect(() => {
if (paused) {
pauseVisualizationHandler();
} else {
resumeVisualizationHandler();
}
}, [paused]);
return (
<button id={"pausehandler"} onClick={handlePause}>
{paused ? `RESUME` : `PAUSE`}
</button>
);
}
EDIT: MAYBE YOU DON'T NEED LOCAL STATE AT ALL
function App() {
const handleMode = (type) => {
if(type === 'PAUSE'){
// do PAUSE function
}
if(type === 'RESUME'){
// do RESUME function
}
if(type === 'FAST'){
// do FAST function
}
if(type === 'SLOW'){
// do SLOW function
}
dispatch({
type,
});
};
return (
<>
<button id={"pausehandler"} onClick={(e) => handleMode(`PAUSE`)}>
{`PAUSE`}
</button>
<button id={"pausehandler"} onClick={(e) => handleMode(`RESUME`)}>
{`RESUME`}
</button>
<button id={"pausehandler"} onClick={(e) => handleMode(`FAST`)}>
{`FAST`}
</button>
<button id={"pausehandler"} onClick={(e) => handleMode(`SLOW`)}>
{`SLOW`}
</button>
</>
);
}
and here is the reducer:
const initialState = {
type: "play",
};
const animationStateReducer = (state = initialState, action) => {
const { type } = action;
switch (type) {
case "PAUSE":
return {
...state,
type,
};
case "RESUME":
return {
...state,
type,
};
case "FAST":
return {
...state,
type,
};
case "SLOW":
return {
...state,
type,
};
default:
return state;
}
};
Upvotes: 1