Search code examples
javascriptreactjsreact-nativereact-reduxredux-thunk

how to call the reducer action inside hook function


I have one reducer that includes two actions, one is set up some state shouldUpdateTime to true/false and the other action is reset the state to initialState as false I would like to call the action resetShouldUpdateTime under hook useUpdateTime after some api request triggered

I think I cannt mutate the state inside the hook function but how can I do it?

//clockReducers
interface ReducerValue {
  shouldUpdateTime: boolean;
}

export const initialState: ReducerValue = {
  shouldUpdateTime: false,
};

export const clockSlice = createSlice({
  name: 'clock',
  initialState,
  reducers: {
    setShouldUpdateTime: (state: ReducerValue, action: PayloadAction<boolean>) => {
      return {...state, shouldUpdateTime: action.payload};
    },

    resetShouldUpdateTime: (state: ReducerValue) => {
      return {...state, shouldUpdateTime: false};
    },
  },
});

export const {
  setShouldUpdateTime
} = clockSlice.actions;

export const clockReducer = clockSlice.reducer;

// middleware for updateTime
const updateTimeMiddleware = (action: AnyAction): AppThunk => {
  return async (dispatch, getState) => {
    const prevTime = getState()?.unitTime || {};
    dispatch(action)
    const newTime = getState()?.unitTime || {};
    dispatch(setShouldUpdateTime(prevTime > newTime));
  };
};

// hook
function useUpdateTime(){
  const shouldUpdateTime = useSelector(
    (state: AppState) => state.clockReducer.shouldUpdateTime
  );
  ... do some api request
  // I would like to call resetShouldUpdateTime action to set shouldUpdateTime state to false
}


export default function App() {
  const onClickHandler = useCallBack(() =>{
    useDispatch(updateTimeMiddleware(someAction))
  })
  return (
    <div className="App">
      <button onClick={onClickHandler}>Hello CodeSandbox</button>
    </div>
  );
}

Solution

  • In your custom hook you can get a reference to the Redux store's dispatch function with useDispatch.

    The object returned from createSlice looks like

    {
        name : string,
        reducer : ReducerFunction,
        actions : Record<string, ActionCreator>,
        caseReducers: Record<string, CaseReducer>
    }
    
    

    Each function defined in the reducers argument will have a corresponding action creator generated using createAction and included in the result's actions field using the same function name.

    So you can use the store's dispatch function together with the resetShouldUpdateTime action like this:

    function useUpdateTime() {
      const dispatch = useDispatch();
      //... do some api request
      // I would like to call resetShouldUpdateTime action to set shouldUpdateTime state to false
      dispatch(clockSlice.actions.resetShouldUpdateTime());
    }