Redux-saga 捕获错误并显示通知

问题描述 投票:0回答:1

我遇到了一个问题,我正在寻找解决它的最佳解决方案。我想在出现错误时在仪表板上显示通知。为了实现这一目标:

我正在使用 Redux-Saga 来捕获错误并将其存储在我的减速器中,如下所示:

agencySaga.js

export function* getAgencies() {
  try {
    const agencies = yield call(getAgenciesService);
    const data = agencies?.data;
    if (data) {
      yield put(getAgenciesAction.success(agencies.data));
    }
  } catch (err) {
    yield put(getAgenciesAction.failure(err));
  }
}

agencyReducer.js

import { AGENCIES, AGENCIESDETAILS, AGENCY } from '../actions/agencyAction';
import formatErrorMessage from '../utils/errorMessage';

const INITIAL_STATE = {
  agencies: null, agenciesDetails: null, message: null, loading: false,
};

const agencyReducer = (state = INITIAL_STATE, action) => {
  const { type, payload } = action;

  switch (type) {
    case AGENCIES.FETCH.REQUEST:
      return { ...state, loading: true, message: null };
    case AGENCIES.FETCH.SUCCESS:
      return {...state, agencies: payload, loading: false, message: null };
    case AGENCIES.FETCH.FAILURE:
      return { ...state, loading: false, message: formatErrorMessage(payload, 'agencies') };

然后,我在仪表板上显示通知。

仪表板.jsx

  const { agencies, loading, message } = useSelector((state) => state.agencies);

  useEffect(() => {
    if (message) {
      notification.error({
        message: message.title,
        description: message.description,
      });
    }
  }, [message]);

问题模拟:

  1. 案例1:API无法访问,我们进入saga的catch块,商店中的消息被更新,通知显示在仪表板上。一切正常。

  2. 案例2:API可访问。我刷新页面,初始渲染仍然显示通知,因为商店中的消息仍然设置,直到触发

    AGENCIES.FETCH.REQUEST
    AGENCIES.FETCH.SUCCESS
    将消息重置为
    null

问题似乎出在这个

useEffect
,因为我尝试了如下所示的方法,它有效,但这不是我正在寻找的结果。我想显示我的通知。

Dashboard.jsx

 return (
    <PageContainer className="dashboard" screenHeight={window.innerHeight}>
      <AgenciesDetails />
      {message && <div>{message.title}</div>}
      {renderComponentsList()}
    </PageContainer>
  );

在遵循最佳实践的同时,您有解决此问题的解决方案吗?预先感谢您的回复。

杰夫

reactjs notifications render store redux-saga
1个回答
0
投票

通知触发后,您可以清除

message
状态。

实施示例:

agencyReducer.js

const agencyReducer = (state = INITIAL_STATE, action) => {
  const { type, payload } = action;

  switch (type) {
    case AGENCIES.FETCH.REQUEST:
      return { ...state, loading: true, message: null };

    case AGENCIES.FETCH.SUCCESS:
      return {
        ...state,
        agencies: payload,
        loading: false,
        message: null,
      };

    case AGENCIES.FETCH.FAILURE:
      return {
        ...state,
        loading: false,
        message: formatErrorMessage(payload, 'agencies')
      };

    case AGENCIES.FETCH.CLEAR_MESSAGE:
      return { ...state, message: null };

    ...
  }
};

“获取代理机构操作”

const clearMessage = () => ({
  type: AGENCIES.FETCH.CLEAR_MESSAGE
});

仪表板.jsx

const dispatch = useDispatch();

const { agencies, loading, message } = useSelector((state) => state.agencies);

useEffect(() => {
  if (message) {
    notification.error({
      message: message.title,
      description: message.description,
    });
    dispatch(getAgenciesAction.clearMessage());
  }
}, [dispatch, message]);

如果您不想清除

message
状态,因为您希望 错误持续到成功,您可以类似地使用 some 状态表示已触发通知,在触发通知时将其设置为“显示” ,并在下次成功或失败时将其重置为“未显示”。

如果

notification
是全局引用,您甚至可以直接从传奇中触发它。

示例:

import formatErrorMessage from '../utils/errorMessage';
import notification from '../path/to/notification';

export function* getAgencies() {
  try {
    const agencies = yield call(getAgenciesService);
    const data = agencies?.data;
    if (data) {
      yield put(getAgenciesAction.success(agencies.data));
    }
  } catch (err) {
    const message = formatErrorMessage(err);
    notification.error({
      message: message.title,
      description: message.description,
    });
    yield put(getAgenciesAction.failure(err));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.