Hello! I am working on the React Drum Pad project. I have been using useReducer (the React hook, not Redux) to organize/dispatch my actions, and useEffect to add an event listener to a component. Here are the relevant parts of what I have:
My reducer function:
function reducer(state, action){
switch(action.type) {
case ACTIONS.TOGGLE_POWER:
return {...state, isPowerOn: !state.isPowerOn, isPlaying: false }
case ACTIONS.TAP_KEY:
getDrumKitData();
handleAudioKeyDown(action.payload);
return {...state, isPlaying: false}
default:
return state;
}
}
Power Button component:
export default function Power(){
/*I have wrapped everything in a Context containing the state/dispatch values from useReducer function*/
const globalState = useContext(GlobalStateContext);
const dispatch = useContext(DispatchContext);
const state = globalState.state;
return (
<div id="power">
<button className={state.isPowerOn ? "power-on" : "power-off"} id="power-button" onClick={()=> dispatch({type: ACTIONS.TOGGLE_POWER})}>
<FontAwesomeIcon icon={faPowerOff} aria-hidden="true" />
</button>
</div>
);
}
Relevant parts of Buttons Component:
export default function Buttons(){
const globalState = useContext(GlobalStateContext);
const dispatch = useContext(DispatchContext);
const state = globalState.state;
/*I have been trying to dispatch an action from here based on whether or not the power is on, but it didn't work so I have tried debugging:*/
useEffect(() => {
window.addEventListener('keydown', ()=>console.log(state));
return ()=> {window.removeEventListener('keydown', ()=>console.log(state))};
}, [state.isPowerOn]);
return(/*buttons component is here, but not relevant for question*/);
}
When I tap a key and the power is on, it prints a copy of the state object to the console. Fine and dandy. But when I turn the power off by clicking the power button (as dispatched in my reducer function) and then do a keydown, it prints two copies of the state to the console, one where isPowerOn is true and one where it is false. Then I turn the power on again and it prints three conflicting copies to the console-- true false true–and then four, and so forth. No wonder it isn’t working. Why is it doing that? Shouldn’t it just be creating a shallow copy of the state and updating the isPowerOn value? Do I need to use the spread operator or destructure my state object somehow? Please help!
Thank you so much.