繁体   English   中英

提取失败会导致组件生命周期无限循环

[英]Failed fetch causes infinite component life-cycle loop

使用连接的容器,我有一个减速器,该减速器由高阶减速器(如下所示)包裹起来以捕获并处理错误。 componentDidMount期间调用获取请求且失败时,连接的容器将自行卸载componentWillUnmount 这将在容器中造成无限循环,因为它将再次安装,获取将失败并且容器将自行卸载。

有什么想法为什么在连接组件中具有高阶减速器会导致这种情况?

处理高阶减速器时出错:

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)));
};

根据我们在评论中的对话:

通常,组件会卸载,因为它们的父级不再渲染它们。 父母是什么样子? 您可能会在哪里查找为什么要卸载组件。

我不知道组件可以自行卸载的任何情况(没有hack)

我认为您只需要捕获错误,而不是让React安装代码捕获异常。

try {
   this.props.fetch(....);
}
catch (e) {
   //Do whatever is appropriate to handle the fetch failure. Maybe you want...
   this.setState({ error: {hasError: true, message: '' + e});
}

我认为上面的setState()调用不适合您预期的reducer实现,但这是您可以解决(或询问更多问题)的单独问题。 您的问题的主要部分似乎是停止卸载/重新安装行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM