0

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>
  );
}
jacobcan118
  • 7,797
  • 12
  • 50
  • 95

1 Answers1

1

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());
}
ksav
  • 20,015
  • 6
  • 46
  • 66
  • hm...i have tried it but it is the error I got `Warning: Cannot update a component (`xxx`) while rendering a different component (`yyyyy`). To locate the bad setState() call inside `yyyy`` – jacobcan118 Jul 17 '21 at 04:19
  • Perhaps you should add a link to your CodeSandbox to the question – ksav Jul 17 '21 at 04:20
  • https://stackoverflow.com/questions/62336340/cannot-update-a-component-while-rendering-a-different-component-warning – ksav Jul 19 '21 at 00:00