首页 > 解决方案 > Redux 工具包警报删除 setTimeout

问题描述

我对 redux-toolkit 完全陌生并且仍在学习它,我在这一步有点受阻,因为我不知道如何使用 redux-toolkit 来实现它。

我在我的 redux 商店中构建了一个 toasts 系统,这是我的操作。

我的行动

const setAlert = (msg, alertType, timeout = 5000) => (dispatch) => {
  const id = uuidv4();
  dispatch({
    type: SET_ALERT,
    payload: { msg, alertType, id },
  });

  setTimeout(() => dispatch({ type: REMOVE_ALERT, payload: id }), timeout);
};

我的旧减速机

export default function (state = initialState, action) {
  const { type, payload } = action;

  switch (type) {
    case SET_ALERT:
      return [...state, payload];
    case REMOVE_ALERT:
      return state.filter((alert) => alert.id !== payload);
    default:
      return state;
  }
}

我正在考虑使用 useEffect 创建一个反应组件以在警报数组长于 0 时进行渲染,但我认为这将是矫枉过正。

我也在考虑创建 createAsyncThunk 操作,但我需要返回警报的值,因此我无法设置 setTimeout 作为函数返回。

有没有办法在减速器中获取调度函数,以便在超时后调度 removeAlert?

const initialState: [] = [];
const alertSlice = createSlice({
  name: 'alert',
  initialState,
  reducers: {
    setAlert(state, action) {
      const id = uuidv4();
      [...state, action.payload];
      toast[action.payload.alertType](msg);
      setTimeout(() => dispatch(removeAlert(id)), timeout);
    },
    removeAlert(state, action) {
      return state.filter((alert) => alert.id !== action.payload);
    },
  },
});

标签: javascriptreactjsreduxredux-toolkit

解决方案


我用手写的 thunk 解决了它

https://redux.js.org/usage/writing-logic-thunks#async-logic-and-side-effects

const initialState: [] = [];

const alertSlice = createSlice({
  name: 'alert',
  initialState,
  reducers: {
    sA(state, action) {
      [...state, action.payload];
      toast[action.payload.alertType](action.payload.msg);
    },
    rA(state, action) {
      return state.filter((a) => a.id !== action.payload.id);
    },
  },
});

export const { sA, rA } = alertSlice.actions;

export function alert(msg, alertType, timeout = 5000) {
  return async (dispatch, getState) => {
    const id = uuidv4();
    const obj = {
      msg,
      alertType,
      timeout,
      id,
    };

    dispatch(sA(obj));
    setTimeout(() => dispatch(rA(id)), timeout);
  };
}

export default alertSlice;

推荐阅读