Skip to content
Advertisement

Reactjs custom hook won’t fire using an if/else in useEffect?

I extracted my reducer function in a custom hook. When I try to fire decreaseMinutes from the custom hook nothing happens. The other functions of the hook work great tough – such as toggleActive– (probably because they are in an event handler).

Any idea how I can solve this?

Reducer + Hook Component:

import { useReducer } from "react";
import { defaultState } from "../setDefaultState";

const DECREASE_MINUTES = "decrease minutes";
const DECREASE_SECONDS = "decrease seconds";
const TOGGLE_ISACTIVE = "toggle isActive";
const RESET = "handle reset";

export const timerReducer = (state, action) => {
  switch (action.type) {
    case DECREASE_SECONDS:
      console.log("decrease sec works");
      return {
        ...state,
        seconds: state.seconds - 1,
      };
    case DECREASE_MINUTES:
      return { ...state, minutes: state.minutes - 1, seconds: 59 };
    case TOGGLE_ISACTIVE:
      return { ...state, isActive: !state.isActive };
    case RESET:
      return {
        ...state,
        seconds: action.payloads.seconds,
        minutes: action.payloads.minutes,
        isActive: !state.isActive,
      };
    default:
      return state;
  }
};
//extracted custom Hook
export function useTimer() {
  const [timerState, dispatch] = useReducer(timerReducer, defaultState);

  const decreaseSeconds = () => dispatch({ type: DECREASE_SECONDS }, console.log("decrease hook works"));
  const decreaseMinutes = () => dispatch({ type: DECREASE_MINUTES });
  const toggleActive = () => dispatch({ type: TOGGLE_ISACTIVE });
  const reset = () =>
    dispatch({
      type: RESET,
      payloads: {
        seconds: defaultState.seconds,
        minutes: defaultState.minutes,
        isActive: !state.isActive,
      },
    });

  return {
    timerState,
    decreaseMinutes,
    decreaseSeconds,
    toggleActive,
    reset,
  };
}

Main Component:

const Timer = () => {

  const { timerState, decreaseMinutes, decreaseSeconds, toggleActive, reset } = useTimer();
  const [dateState, dispatchDate] = useReducer(dateReducer, defaultState);

 useEffect(() => {
    let interval = null;

    // reduce seconds and minutes by 1
    if (timerState.isActive) {
      interval = setInterval(() => {
        if (timerState.seconds > 0) {
          decreaseSeconds; //--> this is what I'm trying to fire

          console.log("conditional works");
        } else if (timerState.seconds === 0) {
          if (timerState.minutes === 0) {
            clearInterval(interval);
          } else {
            decreaseMinutes;
          }
        }
      }, 1000);
      return () => clearInterval(interval);
    }
  }, [timerState.isActive, timerState.seconds, timerState.minutes]);

Advertisement

Answer

You need to call it. Since you defined them as function. Like following:

decreaseMinutes();
decreaseSeconds();
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement