對於連接的容器,我有一個reducer,它被更高階的reducer(如下所示)包裹以捕獲和處理錯誤。當在componentDidMount
期間調用提取請求並且失敗時,連接的容器將自行卸載componentWillUnmount
。這將導致容器中的無限循環,因爲它將再次裝入,取出將失敗,並且容器將自行卸載。失敗的提取導致無限的組件生命週期循環
任何想法爲什麼在連接組件中具有更高階的reducer造成這種情況?
錯誤處理高階減速器:
export const errorHandler = (reducer: (state: any, action: { type: string }, initialState: any) => {}) => {
const errorState = fromJS({
error: {
hasError: false,
message: "",
},
});
const initialState = errorState.merge(reducer(undefined, { type: undefined }, undefined));
return (state = initialState, action) => {
switch (action.type) {
case ACTIONS.SET_ERROR:
return state.setIn(["error", "hasError"], true)
.setIn(["error", "message"], action.message);
case ACTIONS.CLEAR_ERROR:
return state.set("error", errorState.get("error"));
default:
return reducer(state, action, initialState);
}
};
};
實施例容器:
class Page extends Component {
componentDidMount() {
this.props.fetch(....);
}
componentWillUnmount() {
this.props.clearData();
this.props.cancelRequests();
}
}
export default connect(
(state) => ({
error: state.data.get("error", ""),
}),
{
clearError,
clearData,
cancelRequests,
},
)(Page);
實施例減速機:
export fetch =() => ({
type: ACTIONS.FETCH
});
export default errorHandler((state, action) => {
switch(action.type) {
default:
return state;
}
}));
史詩:
export const fetch = (action$: any, store: any, api: API) => {
return action$.ofType(ACTIONS.FETCH)
.mergeMap((action: any) =>
fromPromise(api.fetch(action.data))
.pluck("Data")
.map(data) =>
fetchFulfilled(data),
)
.catch((response) => {
const toPromise = typeof response.json === "function" ? response.json() : new Promise((resolve) => resolve(response));
return fromPromise(toPromise)
.pluck("Message")
.map((Message: string) =>
setError(Message));
})
.takeUntil(action$.ofType(ACTIONS.CANCEL_REQUESTS)));
};
通常組件卸載,因爲他們的父母不再使他們的任何情況組件可以卸載本身(不包括黑客)。的父項是什麼樣的? (我實際上沒有意識到組件可以卸載自身的任何情況,但也許有可能) –
jayphelps
這正是問題所在。在深入研究這個問題之後,我發現了一個使用相同的errorHandler()高階簡化器的父組件。每當setError()被解僱時,父母都會捕獲該事件,並重新展示其子項(包括頁面在內)。切換使用全局setError()動作完全解決了這個問題。 – dpaulus