我遇到了一个问题,我正在寻找解决它的最佳解决方案。我想在出现错误时在仪表板上显示通知。为了实现这一目标:
我正在使用 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:API无法访问,我们进入saga的catch块,商店中的消息被更新,通知显示在仪表板上。一切正常。
案例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>
);
在遵循最佳实践的同时,您有解决此问题的解决方案吗?预先感谢您的回复。
杰夫
通知触发后,您可以清除
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));
}
}